在多线程上编写我的基本程序,我遇到了一些困难。
在下面的程序中,如果我在位置1休眠,则打印的共享数据的值始终为10,而在第2位保持睡眠,共享数据的值始终为0.
为什么会出现这种输出? 如何决定我们应该在哪个地方睡觉。 这是否意味着如果我们在互斥锁中放置一个睡眠,则根本不会执行另一个线程,因此共享数据为0。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
pthread_mutex_t lock;
int shared_data = 0;
void * function(void *arg)
{
int i ;
for(i =0; i < 10; i++)
{
pthread_mutex_lock(&lock);
shared_data++;
pthread_mutex_unlock(&lock);
}
pthread_exit(NULL);
}
int main()
{
pthread_t thread;
void * exit_status;
int i;
pthread_mutex_init(&lock, NULL);
i = pthread_create(&thread, NULL, function, NULL);
for(i =0; i < 10; i++)
{
sleep(1); //POSITION 1
pthread_mutex_lock(&lock);
//sleep(1); //POSITION 2
printf("Shared data value is %d\n", shared_data);
pthread_mutex_unlock(&lock);
}
pthread_join(thread, &exit_status);
pthread_mutex_destroy(&lock);
}
答案 0 :(得分:2)
当您在锁定互斥锁之前休眠时,您将给另一个线程足够的时间来更改共享变量的值。这就是为什么你在位置#1中看到“睡眠”值为“10”的原因。
当您首先获取互斥锁时,您可以足够快地锁定它,以便在其他线程有机会修改它之前打印出该值。另一个线程坐在pthread_mutex_lock()
调用上阻塞,直到你的主线程完成睡眠并解锁它。此时,第二个线程最终运行并更改该值。这就是为什么你在位置#2处看到“睡眠”值为“0”的原因。
这是竞争条件的经典案例。在另一台计算机上,相同的代码在位置#2处sleep
调用时可能不会显示“0”。在主线程锁定互斥锁之前,第二个线程完全有可能一次或两次更改变量的值。互斥锁可以确保两个线程不会同时访问同一个变量,但是它无法控制两个线程访问它的顺序。
答案 1 :(得分:2)
我在这里有完整的解释,但最终删除了它。这是一个基本的同步问题,你应该能够在处理更复杂的事情之前跟踪和识别它。
但我会给你一个提示:只有位置1的sleep()
才重要;锁中的另一个是无关紧要的,只要它不会改变锁外的代码。