我有这个主要代码,它以函数“ doit”作为参数之一执行pthread_create。我有三个doit函数,其中每个函数的P和V放置位置不同或根本没有P和V。我的问题是,每个输出会有何不同?更具体地说,每个doit函数可能会有什么输出?
到目前为止,我所知道的是P(&sem)会将sem值变成0,V将该值变成1。但是,我很难解释它如何影响代码。
到目前为止,我认为doit函数#1将导致 1个 2 3 因为printf和i = i + 1受P(&sem)和V(&sem)很好地保护。
在我看来,所有具有doit函数#2的可能输出都是 1,2,3 /// 1、3、3 /// 2、2、3 /// 2、3、3 /// 3 3 3 如果我错了,请纠正我。
但是,我真的不确定在可能的输出方面执行doit函数3时多线程会发生什么。谢谢您的帮助。
sem_t sem;
/* semaphore */
int main(){
int j;
pthread_t tids[3];
sem_init(&sem, 0,1);
for (j=0; j<3; j++) {
pthread_create(&tids[j], NULL, doit, NULL);
}
for (j=0; j<3; j++) {
pthread_join(&tids[j], NULL);
}
return 0;
}
doit# 1.
int i = 0;
void *doit(void *arg){
P(&sem);
i = i + 1;
printf("%d\n", i);
V(&sem);
}
doit #2.
int i = 0;
void *doit(void *arg){
P(&sem);
i = i + 1;
V(&sem);
printf("%d\n", i);
}
doit #3.
int i = 0;
void *doit(void *arg){
i = i + 1;
printf("%d\n", i);
}
答案 0 :(得分:0)
第一个程序将打印
1
2
3
这是唯一受 P / V 正确保护对i
的所有访问的程序。
其他2个程序的行为是未定义,因为一个线程中的写入可能与另一线程中的读取同时发生,并且根据{{3} }:
- 如果程序的执行在不同的线程中包含两个冲突的动作,则其中至少一个不是原子的,并且两个动作都没有发生在另一个线程上,则该程序的执行将引起数据争用。任何此类数据争用都会导致未定义的行为。
- 如果两个表达式求值之一修改一个内存位置,而另一个表达式读取或修改了相同的内存位置,则冲突。
通常,这类作业要求找出2与3之间的差异。这是错误的。从C角度来看,您已经打开了Pandora的盒子,一切皆有可能。