Multithreading 为什么cond变量不是原子释放的?
以下代码可以在“Pthreads编程”(O'Reilly media)一书中找到:Multithreading 为什么cond变量不是原子释放的?,multithreading,thread-safety,pthreads,cthreads,Multithreading,Thread Safety,Pthreads,Cthreads,以下代码可以在“Pthreads编程”(O'Reilly media)一书中找到: 有人知道为什么会发生这种情况吗?线程可以按任何顺序执行,除非您强制执行某些特定的顺序 您强制执行的唯一命令是,watch\u count不能前进,而count小于或等于watch\u count。这显然没有发生 如果需要强制执行任何其他排序,则需要编写代码来执行。否则,线程可以按任何顺序执行。一个好的实现不会频繁地切换线程,而且您可能有一个好的实现 你对它会“马上”走向它的期望似乎没有任何根据。其他线程已经在运行
有人知道为什么会发生这种情况吗?线程可以按任何顺序执行,除非您强制执行某些特定的顺序 您强制执行的唯一命令是,
watch\u count
不能前进,而count
小于或等于watch\u count
。这显然没有发生
如果需要强制执行任何其他排序,则需要编写代码来执行。否则,线程可以按任何顺序执行。一个好的实现不会频繁地切换线程,而且您可能有一个好的实现
你对它会“马上”走向它的期望似乎没有任何根据。其他线程已经在运行并且没有等待,那么为什么它们不应该继续前进呢?这两个inc\u线程已经在运行,它们从不等待任何东西
pthread_cond_signal
函数会导致当前正在等待条件变量的一个线程停止等待条件变量。在获取互斥量之前,它仍然无法前进,因为它需要互斥量来检查是否可以退出while
条件。还有另外两个线程在争夺互斥锁,不能保证它会赢
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define TCOUNT 10
#define WATCH_COUNT 12
int count = 0;
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t count_threshold_cv = PTHREAD_COND_INITIALIZER;
int thread_ids[3] = {0,1,2};
void watch_count(int *idp);
void inc_count(int *idp);
extern int
main(void)
{
pthread_t threads[3];
pthread_create(&threads[0], NULL, inc_count, &thread_ids[0]);
pthread_create(&threads[1], NULL, inc_count, &thread_ids[1]);
pthread_create(&threads[2], NULL, watch_count, &thread_ids[2]);
for(int i=0; i<3; i++)
pthread_join(threads[i],NULL);
return 0;
}
void watch_count(int *idp)
{
pthread_mutex_lock(&count_mutex);
printf("Waiting condition\n");
while(count <= WATCH_COUNT)
{
pthread_cond_wait(&count_threshold_cv,&count_mutex);
printf("watch_count(): Thread %d, Count is %d\n", *idp, count);
}
pthread_mutex_unlock(&count_mutex);
}
void inc_count(int *idp)
{
for(int i=0; i<TCOUNT; i++)
{
pthread_mutex_lock(&count_mutex);
count++;
printf("inc_counter(): Thread %d, old count %d, new count %d\n", *idp, count-1, count);
if(count == WATCH_COUNT)
{
printf("release\n");
pthread_cond_signal(&count_threshold_cv);
}
pthread_mutex_unlock(&count_mutex);
}
}
inc_counter(): Thread 0, old count 0, new count 1
inc_counter(): Thread 1, old count 1, new count 2
Waiting condition
inc_counter(): Thread 0, old count 2, new count 3
inc_counter(): Thread 1, old count 3, new count 4
inc_counter(): Thread 0, old count 4, new count 5
inc_counter(): Thread 1, old count 5, new count 6
inc_counter(): Thread 0, old count 6, new count 7
inc_counter(): Thread 1, old count 7, new count 8
inc_counter(): Thread 0, old count 8, new count 9
inc_counter(): Thread 1, old count 9, new count 10
inc_counter(): Thread 0, old count 10, new count 11
inc_counter(): Thread 1, old count 11, new count 12
releasing
inc_counter(): Thread 0, old count 12, new count 13
inc_counter(): Thread 1, old count 13, new count 14
watch_count(): Thread 2, Count is 14
inc_counter(): Thread 0, old count 14, new count 15
inc_counter(): Thread 1, old count 15, new count 16
inc_counter(): Thread 0, old count 16, new count 17
inc_counter(): Thread 1, old count 17, new count 18
inc_counter(): Thread 0, old count 18, new count 19
inc_counter(): Thread 1, old count 19, new count 20