c - 在哲学家就餐中使用 Pthreads 显示死锁

标签 c pthreads posix dining-philosopher

我们的作业是展示哲学家就餐问题的僵局。我们已经对所有内容进行了编码,并且代码可以编译,但是当运行代码时,其中一位哲学家最终会吃东西。那么这是否意味着死锁实际上不会发生?

#include <pthread.h>
#include <stdio.h>

#define number_philo 5


pthread_mutex_t cutlery[number_philo];


void* philosopher (void* number)

{

    int my_num = *((int*)number);

    while (1)

    {


        printf("\n Philosopher %d is thinking.\n",my_num);


        pthread_mutex_lock (&cutlery[my_num]);
        printf("\nPhilosopher %d has left cutlery. \n",my_num);
        sleep(3);
        pthread_mutex_lock (&cutlery[(my_num + 1) %  number_philo]);
        printf("\nPhilosopher %d has right cutlery. \n",my_num);



        printf("\n Philosopher %d eating.\n", my_num);


        printf("\n Philosopher %d done.\n", my_num);


        pthread_mutex_unlock (&cutlery[(my_num + 1) % number_philo]);

        pthread_mutex_unlock (&cutlery[my_num]);
        printf("\nPhilosopher %d no longer has cutlery.\n", my_num);
    }

    return NULL;

}


int main ()

{

    int i;

    pthread_t phils[number_philo];

    void* return_val;


    for (i = 0; i < number_philo; i++)

        pthread_mutex_init (&cutlery[i], NULL);


    for (i = 0; i < number_philo; i++)

        pthread_create (&phils[i], NULL, philosopher, &i);


    for (i = 0; i < number_philo; i++)

        pthread_join (phils[i], &return_val);


    return 0;

}

这是输出:output

最佳答案

问题出在这里:

  pthread_create (&phils[i], NULL, philosopher, &i);

您将指向同一变量i的指针传递给每个线程,并且这些线程(和主线程)都以一种活泼的方式访问i。你会得到多个哲学家使用相同的数字和一些根本没有使用的数字。

您需要为每个哲学家提供自己的变量来读取,或者等待它读取i,然后再循环并更改i。前者的一个例子:

int phil_num[number_philo];

/* ... */

for (i = 0; i < number_philo; i++)
{
    phil_num[i] = i;
    pthread_create (&phils[i], NULL, philosopher, &phil_num[i]);
}

关于c - 在哲学家就餐中使用 Pthreads 显示死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40158099/

相关文章:

java - 带有比较加三元运算符表达式的表达式 "a==1 ? 1 : 0"是原子的吗?

python - 如何将 stdout 和 stderr 重定向到管道但保持有序

bash - 使用 POSIX Shell 将 CamelCase 转换为 lowerCamelCase

c - 解析文本文件中由逗号或空格分隔的单词 - 我可以用 scanf 克服逗号吗?

c - 如何在 C 中将两个 #define 作为关键字附加在一起?

c - swr_convert float 平面到 S16

c++ - 在 Windows 中使用 PTHREAD 互斥?

linux - pthread_self() 和 gettid() 有什么区别?我应该使用哪一个?

linux - BASH: 发送 SIGTSTP 信号 (ctrl+z)

c - 使用 TDD 的 Hello world 和使用 Eclipse CDT + Jenkins + Maven 的持续集成