In my code, I want to create three threads one by one. So I use a global variable to control this. But it does not work as I design. It is blocked on a while loop. Here is my code:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
int startb = 0, startc=0;
.......
int main(int argc, char* argv[]){
pthread_t ida,idb,idc;
int result;
pthread_key_create(&stKey, TsdFree);
result = pthread_create(&idb, NULL, (void*)printB, NULL);
if(0 != result)
{
printf("create thread B error\n");
}
while (1 != startb); /*block here*/
result = pthread_create(&idc, NULL, (void*)printC, NULL);
........
}
Thread B:
void printB(void* para)
{
for(int i=0; i<2;++i)
{
pthread_mutex_lock(&mutex);
startb = 1;
pthread_cond_wait(&conda, &mutex);
pthread_mutex_unlock(&mutex);
printf("B\n");
pthread_mutex_lock(&mutex);
pthread_cond_signal(&condb);
pthread_mutex_unlock(&mutex);
}
pthread_exit(0);
}
I use gdb to see the value of the variable of startb. it turns out that the value of startb has already been 1:
Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". 0x000000000040068b in main (argc=, argv=) at pthread.c:57 57 while (1 != startb); (gdb) bt
0 0x000000000040068b in main (argc=, argv=) at pthread.c:57 (gdb) p startb $1 = 1 (gdb) bt
0 0x000000000040068b in main (argc=, argv=) at pthread.c:57 (gdb) c
Continuing.
The Call stack of these threads:
main:
[<0>] exit_to_usermode_loop+0x59/0xd0
[<0>] prepare_exit_to_usermode+0x77/0x80
[<0>] retint_user+0x8/0x8
[<0>] 0xffffffffffffffff
thread B:
[<0>] futex_wait_queue_me+0xc4/0x120
[<0>] futex_wait+0x10a/0x250
[<0>] do_futex+0x325/0x500
[<0>] SyS_futex+0x13b/0x180
[<0>] do_syscall_64+0x73/0x130
[<0>] entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[<0>] 0xffffffffffffffff
Can anyone tell me the reason?
void printB(void* para)The signature of a posix thread isvoid * printB( void* para)Note the return type isvoid*notvoid- user3629249main()when the parameters are not used, avoid the two warnings from the compiler about unused parameters by using the signature:int main( void )- user3629249gcc, at a minimum use:-Wall -Wextra -Wconversion -pedantic -std=gnu11) Note other compilers use different options to perform the same thing - user3629249