我在学多线程。关于……
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);
}
}
我想知道代码的控制流程。
As pthread_cond_wait - unlocks the mutex and waits for the condition variable cond to be signaled
我对流动控制的理解是
1)创建线程1、2,并通过thread1控制(考虑单核处理器系统)
2)当在pthread_cond_wait( &condition_var, &count_mutex );
例程void *functionCount1()
中遇到void *functionCount1()
时,它释放锁并等待状态将控制权传递给thread2 void *functionCount1()
。
3)在thread2
中,对变量count
进行检查,并且由于它满足count < COUNT_HALT1 || count > COUNT_HALT2
-它指示thread1
并重新启动是增加count
。
4)重复Steps 2 to 3
,通过thread1
显示1-3
5)对于count 4-7
,thread2正在运行,thread1
和thread2
之间没有交换
6)再次对count 8-10
进行steps 2-3
重复。
我想知道我的理解是否正确?thread1
去睡觉了,thread2
唤醒了它(即线程被切换)到count value 1-3 and 8-10
i.e switching between threads happen 5 times
了吗?
编辑
我要问这个问题的主要问题是,当thread1
遇到pthread_cond_wait( &condition_var, &count_mutex );
时,它是否会进入sleep
状态,并且不会再次成为active
,除非由thread2
发出信号,然后才会增加count
,也就是说,它不会一次递增1-3
,而是每一次增量,它必须等待来自thread2
的信号,然后才能进一步进行。
发布于 2013-05-15 08:07:08
1)线程被创建。控件不传递给thread1,而是由系统调度程序决定执行哪个线程。两个线程都处于活动状态,都应该接收处理器时间,但顺序尚未确定。可能有几个上下文开关,您并不真正控制这一点。
2)正确,thread1进入等待状态,thread2继续工作。同样,控件没有显式传递。
3)是的,thread2会通知条件变量,因此thread1会唤醒并尝试重新获取互斥对象。控件不会立即转到thread1。
一般来说,您应该理解不能真正控制要执行哪个线程;它是系统调度程序的任务,它可以随意放置多少个上下文切换。
UPD:使用条件变量,您可以在多线程环境中控制任务执行的顺序。因此,我认为您的理解或多或少是正确的: thread1正在等待条件变量,等待来自thread2的信号。当接收到信号时,thread1继续执行(在它重新获取互斥之后)。但是线程之间的切换--可能有很多线程,5只是理论上的最小值。
发布于 2013-05-15 08:56:49
第一:从布滕霍夫那里得到这本书,然后学习它。您引用的页面在几个地方都是不正确的,而且作者显然不理解线程本身。
关于您的问题:首先要说的是,您不能知道代码的控制流。这是线程处理的一个特点,在现代处理器上,您经常会发现线程实际上是并行运行的,其中一个内核执行一个线程,另一个内核执行另一个内核。在每个线程中,处理器可以以意想不到的方式重新安排内存访问。这就是为什么你需要互斥,例如。(您提到“考虑单核处理系统”,但在实践中,单核通用系统已经不存在了。)
其次,线程的调度方式取决于操作系统。例如,在您的代码中,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
的所有访问。在您的情况下,锁定和解锁应该在程序循环之外,两个线程都应该等待条件变量。(但这显然是一种人为的情况--实际上,几乎总是会有一个生产者线程和一个消费者线程。)
发布于 2013-05-15 08:06:05
在理想的世界里,是的,但在实践中,并不完全是这样。
你无法预测哪种胎面会先控制住你。是的,它很可能是thread1
,但仍然不能保证。这是您代码中的第一个赛车条件。
当thread2
获得控制权时,它很可能会在没有停止的情况下结束。不管你有多少CPU。原因是它没有无条件的yield
空间。发布mutex
并不意味着any1可以锁定它。这是你代码中的第二个赛车条件。
因此,thread1
将打印11
,这是唯一保证的部分。
https://stackoverflow.com/questions/16559583
复制相似问题