满足条件时,while循环不会停止

时间:2018-12-16 10:14:06

标签: c

在我的代码中,我想一个一个地创建三个线程。所以我使用一个全局变量来控制它。但这在我设计时不起作用。它在while循环中被阻止。这是我的代码:

#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);
........
}

线程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);
}

我使用gdb查看startb变量的值。事实证明startb的值已经是1:

  
    

使用libthread_db启用线程调试]使用主机libthread_db     库“ /lib/x86_64-linux-gnu/libthread_db.so.1”。 0x000000000040068b     在pthread.c:57的main(argc =,argv =)中     57 while(1!= startb); (gdb)bt

         

0 0x000000000040068b在主线程(argc =,argv =)在pthread.c:57(gdb)p startb $ 1 = 1(gdb)bt

         

0 0x000000000040068b在主线程(argc =,argv =)在pthread.c:57(gdb)c

  
     

继续。

这些线程的调用堆栈:

主要:

[<0>] exit_to_usermode_loop+0x59/0xd0
[<0>] prepare_exit_to_usermode+0x77/0x80
[<0>] retint_user+0x8/0x8
[<0>] 0xffffffffffffffff

线程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

有人可以告诉我原因吗?

1 个答案:

答案 0 :(得分:5)

您不能在线程间通信中使用简单变量。就目前情况而言,编译器将在循环中看到

while (1 != startb); /*block here*/

startb的值永远不会被修改,因此将合法在内部将其重写为

if( 1 != startb ){
    while( true );
}

一个等待外部设置标志的循环称为 Spinlock ,正确的自旋锁实现必须小心使用 Atomic Semanticity 和< em> Memory Barriers

不过,对于您打算做的事情,正确的选择是使用 Condition Variable ,这是pthread很好地支持的结构,您已经尝试使用它,但是这样做不正确。