[英]Condition Variable POSIX Thread : C/C++
我正在学习多线程。 关于至于对于有关
http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#SCHEDULING
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER;
void *functionCount1();
void *functionCount2();
int count = 0;
#define COUNT_DONE 10
#define COUNT_HALT1 3
#define COUNT_HALT2 6
main()
{
pthread_t thread1, thread2;
pthread_create( &thread1, NULL, &functionCount1, NULL);
pthread_create( &thread2, NULL, &functionCount2, NULL);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
printf("Final count: %d\n",count);
exit(0);
}
// Write numbers 1-3 and 8-10 as permitted by functionCount2()
void *functionCount1()
{
for(;;)
{
// Lock mutex and then wait for signal to relase mutex
pthread_mutex_lock( &count_mutex );
// Wait while functionCount2() operates on count
// mutex unlocked if condition varialbe in functionCount2() signaled.
pthread_cond_wait( &condition_var, &count_mutex );
count++;
printf("Counter value functionCount1: %d\n",count);
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) return(NULL);
}
}
// Write numbers 4-7
void *functionCount2()
{
for(;;)
{
pthread_mutex_lock( &count_mutex );
if( count < COUNT_HALT1 || count > COUNT_HALT2 )
{
// Condition of if statement has been met.
// Signal to free waiting thread by freeing the mutex.
// Note: functionCount1() is now permitted to modify "count".
pthread_cond_signal( &condition_var );
}
else
{
count++;
printf("Counter value functionCount2: %d\n",count);
}
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) return(NULL);
}
}
我想知道代码的控制流程。
作为pthread_cond_wait - unlocks the mutex and waits for the condition variable cond to be signaled
我对流量控制的了解是
1)创建线程一,二,并将线程1传递给控件(考虑单核处理器系统)
2)遇到pthread_cond_wait( &condition_var, &count_mutex );
在thread1
例程void *functionCount1()
-释放锁定并进入等待状态,将控制权传递给thread2 void *functionCount1()
3)在thread2
中检查变量count
,因为它满足count < COUNT_HALT1 || count > COUNT_HALT2
count < COUNT_HALT1 || count > COUNT_HALT2
它向thread1
发出信号并重新启动以增加count
4)重复Steps 2 to 3
, thread1
1-3
显示1-3
5)对于count 4-7
,线程2处于活动状态,并且thread1
和thread2
之间没有切换
6)对于count 8-10
再次重复steps 2-3
。
我想知道我的理解是否正确? 是否thread1
进入睡眠状态和thread2
将其唤醒(即线程切换)的count value 1-3 and 8-10
ie switching between threads happen 5 times
?
编辑
我主要要问的问题是,知道thread1
在遇到pthread_cond_wait( &condition_var, &count_mutex );
时是否会进入sleep
状态pthread_cond_wait( &condition_var, &count_mutex );
除非thread2
发出信号,否则它将不会再次active
,只有这样递增count
即它不会thread2
增加1-3
,而是每次增加,它必须等待thread2
发出的信号才可以继续进行
首先:取得Butenhof的书,然后进行研究。 您引用的页面在很多地方都是错误的,并且作者显然不了解自己的线程。
关于您的问题:首先要说的是您不知道代码的控制流程。 这是线程的特征,在现代处理器上,您经常会发现线程实际上是并行运行的,一个内核执行一个线程,另一个内核执行另一个线程。 并且在每个线程内,处理器可能会以意外方式重新安排内存访问。 例如,这就是为什么需要互斥锁的原因。 (您提到“考虑单核处理系统”,但实际上,单核通用系统已不存在。)
其次,线程的调度方式取决于操作系统。 例如,在您的代码中, functionCount2
可以一直运行到functionCount1
开始之前的完成为止,这意味着functionCount1
将永远等待。
第三, pthread_cond_wait
的线程可能会虚假地唤醒。 绝对规则是pthread_cond_wait
处于循环中,该循环检查您实际上正在等待的条件。 也许像:
while ( count > COUNT_HALT1 && count < COUNT_HALT2 ) {
pthread_cond_wait( &condition_var, &count_mutex );
}
最后,有时,您正在访问不受互斥锁保护的部分中的count
。 这是未定义的行为; 所有 count
访问都必须受到保护。 在您的情况下,锁定和解锁可能应该在程序循环之外,并且两个线程都应等待条件变量。 (但这显然是人为的情况,在实践中,几乎总是有生产者线程和消费者线程。)
在理想世界中,是的,但实际上却并非如此。
您无法预测哪个胎面首先要控制。 是的,它可能是thread1
,但仍不能保证。 这是代码中的第一个赛车条件。
当thread2
控制thread2
,很可能它将完成而不会停止。 无论您有多少个CPU。 原因是它没有地方无条件 yield
。 您释放mutex
的事实并不意味着any1可以锁定它。 它是您代码中的第二种赛车条件。
因此, thread1
将打印11
,这是唯一保证的部分。
1)创建线程。 控制权不传递给线程1,而是系统调度程序来决定执行哪个线程。 两个线程均处于活动状态,都应接收处理器时间,但是顺序不确定。 可能会有多个上下文切换,您并没有真正控制它。
2)正确,线程1进入等待状态,线程2继续工作。 同样,控制未明确传递。
3)是的,线程2通知条件变量,因此线程1将苏醒并尝试重新获取互斥量。 控件不会立即转到线程1。
通常,您应该了解您无法真正控制要执行的线程。 这是系统调度程序的工作,系统调度程序可以根据需要放置尽可能多的上下文切换。
UPD:使用条件变量,您可以控制多线程环境中任务的执行顺序。 因此,我认为您的理解或多或少是正确的:线程1正在等待条件变量以获取来自线程2的信号。 接收到信号后,thread1继续执行(在重新获取互斥量之后)。 但是在线程之间切换-可能有许多线程,其中5只是理论上的最小值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.