Hi,
At first - thanks for such great C compiler which already implements C11 features, which not exists in many many other C compilers.
However when i try to execute such code:
#include <stdio.h>
#include <threads.h>
#define NUM_THREADS 10
int testFunction(void * data) {
printf("%d-th thread up\n", *(int*)data);
return 0;
}
int main(void) {
thrd_t threadId[NUM_THREADS];
int i;
for (i=0; i < NUM_THREADS; ++i)
if (thrd_create(threadId+i, testFunction, &i) != thrd_success)
printf("%d-th thread create error\n",i);
return 0;
}
I get that some threads not prints it's message. I suspect that this may be thread concurrency problem on shared resource. But this should result in out-of-order prints - not in skipping printf function calls - am I right ? Is it bug in thrd_create() function ? Or it is just "a bug" in my head ? Please explain ...
Disclaimer: I did not read C11 standard yet. But:
There are two problems. The first is:
Quote from: C11 draft
5.1.2.2.3
If the return type of the main function is a type compatible with int, a return from the
initial call to the main function is equivalent to calling the exit function
and later in 7.22.4.4:
The exit function causes normal program termination to occur.
You should somehow wait until your threads terminate. For example, do thrd_sleep in main() before return.
And the second problem is that when you call thrd_start, it waits until execution of the thread begins and returns. And after that there arises a race-condition: sometimes *data is read first by the thread and sometimes ++i in main would be faster. Again you should do some sort of synchronization and wait until your thread reads *data before starting the next thread.
Upd. Here is how it works on my computer:
Quote from: Without synchronization
C:\>pocc /c /MT test.c && polink test.obj && test.exe
5-th thread up
5-th thread up
5-th thread up
5-th thread up
5-th thread up
Quote from: With simple synchronization (looping on boolean value; it is a bad practice!)
C:\>pocc /c /MT test.c && polink test.obj && test.exe
0-th thread up
1-th thread up
2-th thread up
3-th thread up
4-th thread up
5-th thread up
6-th thread up
7-th thread up
8-th thread up
9-th thread up
I am also not sure if the created tasks have the ability to write at the standard-output (without extra code).
I would try to write from each task into an extra file, this is perhaps easier for first expreiments. ;)
Modified for testing. Run it several times to see differences.
#include <stdio.h>
#include <threads.h>
#define NUM_THREADS 10
int testFunction(void * data) {
printf("%d-th thread up\n", *(int*)data);
return 0;
}
int main(void) {
thrd_t threadId[NUM_THREADS];
int i, it[NUM_THREADS];
printf("start\n");
for (i=0; i < NUM_THREADS; ++i) {
it[i] = i;
if (thrd_create(threadId+i, testFunction, &it[i]) != thrd_success)
printf("%d-th thread create error\n",i);
}
printf("end\n");
_getch();
return 0;
}
Thanks to all !
You should wait for the threads in the main program, otherwise it just ends before the threads... Eg. like this:
// wait for all threads
for (i=0; i < NUM_THREADS; ++i)
thrd_join(threadId[i], NULL);