【发布时间】:2019-02-23 08:41:48
【问题描述】:
我正在关注here 的 pthread 教程。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t condition_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_cond = 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);
exit(0);
}
void *functionCount1()
{
for(;;)
{
pthread_mutex_lock( &condition_mutex );
while( count >= COUNT_HALT1 && count <= COUNT_HALT2 )
{
pthread_cond_wait( &condition_cond, &condition_mutex );
}
pthread_mutex_unlock( &condition_mutex );
pthread_mutex_lock( &count_mutex );
count++;
printf("Counter value functionCount1: %d\n",count);
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) return(NULL);
}
}
void *functionCount2()
{
for(;;)
{
pthread_mutex_lock( &condition_mutex );
if( count < COUNT_HALT1 || count > COUNT_HALT2 )
{
pthread_cond_signal( &condition_cond );
}
pthread_mutex_unlock( &condition_mutex );
pthread_mutex_lock( &count_mutex );
count++;
printf("Counter value functionCount2: %d\n",count);
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) return(NULL);
}
}
并且作者补充说,functioncount1() 对于介于值 COUNT_HALT1 和 COUNT_HALT2 之间的值会停止。
示例输出如下:
Counter value functionCount1: 1
Counter value functionCount1: 2
Counter value functionCount1: 3
Counter value functionCount2: 4
Counter value functionCount2: 5
Counter value functionCount2: 6
Counter value functionCount2: 7
Counter value functionCount1: 8
Counter value functionCount1: 9
Counter value functionCount1: 10
Counter value functionCount2: 11
根据我对代码的观察,functionCount2 不应该算 3 吗?在functionCount1 的while 循环中,它在任何值包括 3 上调用wait(),这使我认为3 应该由functionCount2 计数,而不是functionCount1。
为什么不是这样?
【问题讨论】:
-
从多个线程对对象进行非同步、非只读、非原子访问的未定义行为。
-
@EOF 但是有互斥锁来确保我们同步 3 到 6 之间的值。作者甚至提到“唯一可以确保的是 functionCount2 将增加值之间的计数COUNT_HALT1 和 COUNT_HALT2。其他一切都是随机的。”
-
C11 标准草案 n1570:5.1.2.4 多线程执行和数据竞争 4 如果其中一个修改了内存位置,而另一个读取或修改了相同的内存位置,则两个表达式计算冲突. 25 如果一个程序在不同线程中包含两个相互冲突的操作,则该程序的执行包含数据竞争,其中至少一个不是原子的,并且两者都不会在另一个之前发生。任何此类数据竞争都会导致未定义的行为。 未定义。行为。
标签: concurrency pthreads condition-variable