Sca*_*ark 2 c++ multithreading mutex pthreads
我需要解雇一堆线程,并希望优雅地降低它们.
我正在尝试使用pthread_cond_signal/ pthread_cond_wait来实现这一点,但遇到了问题.
这是我的代码.首先是thread_main
static void *thrmain( void * arg )
{
// acquire references to the cond var, mutex, finished flag and
// message queue
.....
while( true )
{
pthread_mutex_lock( &lock );
if ( msq.empty() )
{
// no messages so wait for one.
pthread_cond_wait( &cnd, &lock );
}
// are we finished.
if ( finished )
{
// finished so unlock the mutex and get out of here
pthread_mutex_unlock( &lock );
break;
}
if ( !msg.empty() )
{
// retrieve msg
....
// finished with lock
pthread_mutex_unlock( &lock );
// perform action based on msg
// outside of lock to avoid deadlock
}
else
{
// nothing to do so we're
// finished with the lock.
pthread_mutex_unlock( &lock );
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,这一切看起来都很精致(无论如何).
所以为了拆除我有这种方法的线程
void teardown()
{
// set the global finished var
pthread_mutex_lock( &lock );
finished = true;
pthread_mutex_unlock( &lock );
// loop over the threads, signalling them
for ( int i = 0 ; i < threads.size() ; ++i )
{
// send a signal per thread to wake it up
// and get it to check it's finished flag
pthread_cond_signal( &cnd );
}
// need to loop over the threads and join them.
for ( int i = 0 ; i < threads.size() ; ++i )
{
pthread_join( threads[ i ].tid, NULL );
}
}
Run Code Online (Sandbox Code Playgroud)
现在我知道pthread_cond_signal它不能保证它唤醒哪个线程所以我无法发信号并加入同一个循环.然而,这是一切都出错的地方.pthread_cond_signal如果没有线程等待,则什么都不做,因此可能会有一些线程未被发出信号,因此无法知道退出.
我怎么过来这个.
M.
*****更新*******请不要发布我应该使用pthread_cond_broadcast,因为它表现出完全相同的行为.它只会唤醒一个实际上正在等待cond var的线程.在此期间处理并且稍后再回来等待的任何线程将错过信号并且将被遗忘
首先,你必须改变你的谓词
if ( msq.empty() ) {
// no messages so wait for one.
pthread_cond_wait( &cnd, &lock );
}
Run Code Online (Sandbox Code Playgroud)
至
while ( msq.empty() ) {
// no messages so wait for one.
pthread_cond_wait( &cnd, &lock );
}
Run Code Online (Sandbox Code Playgroud)
这是一个pthreads的事情,你必须保护自己免受虚假的唤醒.
现在你可以改变它
while ( msq.empty() && !finished) {
// no messages so wait for one.
pthread_cond_wait( &cnd, &lock );
}
Run Code Online (Sandbox Code Playgroud)
因为在那次检查之后,你已经测试了是否设置完成并退出,如果是这样,你所要做的就是发出所有线程的信号.
因此,在您的拆解功能中,将循环替换为:
pthread_cond_broadcast(&cond);
Run Code Online (Sandbox Code Playgroud)
这应该确保所有线程都被唤醒,并且将看到finished设置为true和退出.
即使你的线程没有插入,这也是安全的pthread_cond_wait.如果线程正在处理消息,它们将不会获得唤醒信号,但是它们将完成该处理,再次进入循环并查看finished == false并退出.
另一种常见的模式是注入毒药信息.有毒消息只是一个特殊的消息,你的线程可以识别它意味着"停止",你可以在你的队列中放置尽可能多的消息.