C 死锁防止
需要帮助如何防止我写的blow中的代码死锁。或者我需要修复代码以摆脱死锁的任何建议? 另外,当我在Linux中运行时,我遇到了一个分段错误(内核转储)C 死锁防止,c,linux,deadlock,C,Linux,Deadlock,需要帮助如何防止我写的blow中的代码死锁。或者我需要修复代码以摆脱死锁的任何建议? 另外,当我在Linux中运行时,我遇到了一个分段错误(内核转储) #包括 #包括 #包括 #包括 #包括 int-cnt; 整数*比特; int*旧牙咬; sem_t*棒; 无效*罗杰(无效*arg){ int rog=*(int*)arg; 对于(;;){ sem_wait(&(sticks[rog]);//左 sem_wait(&(sticks[(rog+1)%cnt]);//对 咬合[rog]++; se
#包括
#包括
#包括
#包括
#包括
int-cnt;
整数*比特;
int*旧牙咬;
sem_t*棒;
无效*罗杰(无效*arg){
int rog=*(int*)arg;
对于(;;){
sem_wait(&(sticks[rog]);//左
sem_wait(&(sticks[(rog+1)%cnt]);//对
咬合[rog]++;
sem_post(&(sticks[(rog+1)%cnt]);//右
sem_post(&(sticks[rog]);//左
}
pthread_exit(NULL);
返回NULL;
}
int main(int argc,char*argv[]){
int i;
pthread_t*罗杰斯;
int*pos;
cnt=(int)strtol(argv[1],NULL,10);
罗杰斯=(pthread_t*)calloc(cnt,sizeof(pthread_t));
pos=(int*)malloc(cnt*sizeof(int));
比特=(int*)calloc(cnt,sizeof(int));
旧比特=(int*)calloc(cnt,sizeof(int));
棍棒=(sem_t*)calloc(cnt,sizeof(sem_t));
对于(i=0;i
是的,我希望这会死锁。我不知道您使用的是什么cnt
,但让我们假设它是1。在这种情况下,只会创建一个线程。此线程将sem_wait(&(sticks[0])代码>。然后在下一行中,它将sem_wait(&(sticks[(0+1)%1==0])代码>。由于信号量的初始值为1,因此如果不先使用sem\u post
,就不能在同一信号量上等待两次。因此,该线程将永远等待它无法到达的sem\u post
,因为它正在等待
现在考虑“代码> CNT>1 < /代码>的情况(我们只说<代码> CNT==2 < /COD> >以使它更简单)。这将产生thread0和thread1,其中0和1作为参数传递给它们的函数。这种情况可能发生:
- Thread0执行
sem_wait(&(sticks[0])代码>
- 上下文切换:thread1执行sem_wait(&(sticks[1])代码>
- thread1执行
sem_wait(&(sticks[(1+1)%2==0]);//此阻塞是因为thread0已将此信号量扫描为0
- 上下文切换:thread0执行
sem_wait(&(sticks[(0+1)%2==1]);//此阻塞是因为thread1已将此信号量扫描为0
现在,每个线程都在等待另一个线程的sem\u post
,然后才能继续==>死锁。我预计这种情况会随着cnt值的增加而扩展,尽管导致死锁的情况会变得更加复杂
为什么要使用两个信号量来保护单个资源?这个理论听起来不对。这种方法会使你失去原子性(如果我显然错了,请纠正我)
此外,您的比特数
数组也有竞争条件。主线程在读取同步之前没有观察到同步。这可能与seg故障有关。seg故障和死锁?也许去记录一下,加上一个除以零的数?好的,我来咬一口。告诉我们到目前为止您在调试应用程序方面做了哪些工作。哪一行引发segfault?OP,您需要进行一些调试gdb
和valgrind
是非常有用的工具,特别是在涉及分段错误的情况下。更多信息请访问。另外,@user3386109,我的大脑立即将该链接注册为“bistromath”。@JasonMc92啊,这解释了标题。OP意味着气闸阻止。所以我修正了segFault,死锁程序不会结束吗?并持续打印输出?@littlerain根据提供的代码,我希望您的工作线程最终会死锁。所有打印都发生在主循环中,主循环进入无限for
循环,如果dead
变为true,则将退出。这有时可能会发生,但可能不会。永远不会到达pthread\u join
和sem\u destroy
循环。我认为你的信号量数组是一个逻辑错误。你应该只有一个。通过以这种方式使用多个信号量来保护单个资源(bites
array),可以消除线程同步所基于的原子性。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include <semaphore.h>
int cnt;
int *bites;
int *old_bites;
sem_t *sticks;
void *roger(void *arg) {
int rog = *(int*)arg;
for(;;) {
sem_wait(&(sticks[rog])); // left
sem_wait(&(sticks[(rog + 1) % cnt])); // right
bites[rog]++;
sem_post(&(sticks[(rog + 1) % cnt])); // right
sem_post(&(sticks[rog])); // left
}
pthread_exit(NULL);
return NULL;
}
int main(int argc, char *argv[]) {
int i;
pthread_t *rogers;
int *pos;
cnt = (int)strtol(argv[1], NULL, 10);
rogers = (pthread_t *)calloc(cnt, sizeof(pthread_t));
pos = (int *)malloc(cnt * sizeof(int));
bites = (int *)calloc(cnt, sizeof(int));
old_bites = (int *)calloc(cnt, sizeof(int));
sticks = (sem_t *)calloc(cnt, sizeof(sem_t));
for(i = 0; i < cnt; i++) {
sem_init(&(sticks[i]), 0, 1);
}
for(i = 0; i < cnt; i++) {
pos[i] = i;
pthread_create(&(rogers[i]), NULL, roger, (void *)&pos[i]);
}
for(;;) {
bool dead = true;
usleep(50000);
for(i = 0; i < cnt; i++) {
if(bites[i] != old_bites[i]) {
dead = false;
}
}
if(dead) {
exit(EXIT_SUCCESS);
}
for(i = 0; i < cnt; i++) {
printf("%8X", bites[i]);
}
printf("\n");
for(i = 0; i < cnt; i++) {
old_bites[i] = bites[i];
}
}
for(i = 0; i < cnt; i++) {
pthread_join(rogers[i], NULL);
}
for(i = 0; i < cnt; i++) {
sem_destroy(&(sticks[i]));
}
exit(EXIT_SUCCESS);
}