3

我有一个要序列化的三个线程我
使用的 pthreads 是 C++。我正在尝试对输出进行排序,使其成为 {A,B,C,A,B,C,A,B,C,................}。我这样做是因为我有太多想要序列化的线程。我想要的输出是:

Thread A
Thread B
Thread C
Thread A
Thread B
Thread C
Thread A
Thread B
Thread C
Thread A
Thread B
Thread C
........
........

这是我拥有的代码。它有时会挂起,有时会运行一两个循环然后挂起。我想听听你认为问题所在。我的代码是:
thread_test.cpp

#include <stdio.h>
#include <pthread.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int condition = 0;
int count = 0;

void* thread_c( void * arg )
{
   while( 1 )
   {
      pthread_mutex_lock( &mutex );
      while( condition != 2 )
         pthread_cond_wait( &cond, &mutex );
      printf( "Thread C");
      condition = 0;
      pthread_cond_signal( &cond );
      pthread_mutex_unlock( &mutex );
   }

   return( 0 );
}

void* thread_b( void * arg )
{
   while( 1 )
   {
      pthread_mutex_lock( &mutex );
      while( condition != 1 )
         pthread_cond_wait( &cond, &mutex );
      printf( "Thread B" );
      condition = 2;
      pthread_cond_signal( &cond );
      pthread_mutex_unlock( &mutex );
   }

   return( 0 );
}

void*  thread_a( void * arg )
{
   while( 1 )
   {
      pthread_mutex_lock( &mutex );
      while( condition != 0 )
         pthread_cond_wait( &cond, &mutex );
      printf( "Thread A");
      condition = 1;
      pthread_cond_signal( &cond );      
      pthread_mutex_unlock( &mutex );
   }
   return( 0 );
}

int main( void )
{
    pthread_t  thread_a_id;
    pthread_create( &thread_a_id, NULL, &thread_a, NULL );
    pthread_t  thread_b_id;
    pthread_create( &thread_b_id, NULL, &thread_b, NULL );
    pthread_t  thread_c_id;
    pthread_create( &thread_c_id, NULL, &thread_c, NULL );
    int a = pthread_join(thread_a_id, NULL);
    int b = pthread_join(thread_b_id, NULL);
    int c = pthread_join(thread_c_id, NULL);
}

为了编译代码,我使用

g++ -lpthread -std=gnu++0x thread_test.cpp
4

4 回答 4

7

我认为问题在于pthread_cond_signal()可以自由选择它希望的任何等待线程,而您的代码取决于它选择特定线程。

如果我替换pthread_cond_signal()pthread_cond_broadcast(),我将无法再让代码停止。我提到这是一个观察;我还没有说服自己这是一个正确的解决方法。

于 2012-12-10T09:45:33.503 回答
3

Putting aside the question of why you want to serialize the threads to this extent, the problem is that if more than one thread is waiting on the condition, pthread_cond_signal( &cond ) may only wake up one of them to check the condition (actually that's the intended and usually desired behavior - it's more of an accident if more then one waiter is released).

For example, when thread_a() sets condition = 1 it is intending to wake up thread_b. However, thread_c may be waiting at the same time as thread_b. Using pthread_cond_signal you have no control over which of thread_b or thread_c will be released.

Use pthread_cond_broadcast( &cond ) instead to wake all waiters.

于 2012-12-10T09:52:52.027 回答
0

三个条件变量,每个线程一个。线程 A 发出一个线程 B 正在等待的信号,谁发出一个线程 C 等待的信号,谁发出一个线程 A 正在等待的信号......

但是,如果您只想串行运行它们,那么拥有三个可以并行工作的线程有什么用呢?

于 2012-12-10T09:45:18.943 回答
0

你应该看看这个:死锁

于 2012-12-10T09:46:26.113 回答