C 死锁防止

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

需要帮助如何防止我写的blow中的代码死锁。或者我需要修复代码以摆脱死锁的任何建议? 另外,当我在Linux中运行时,我遇到了一个分段错误(内核转储)

#包括
#包括
#包括
#包括
#包括
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);
}