【发布时间】:2018-03-28 01:53:12
【问题描述】:
我对以下 C 代码有疑问。代码本身应该创建 5 个线程来模拟餐饮哲学家问题,其中线程正在访问共享数据。代码如下:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
//creation of the mutex lock, condition variables, and state
pthread_mutex_t mutex;
pthread_cond_t cond_var[5];
enum{THINKING, HUNGRY, EATING}state[5];
//test if possible to get forks
void test(int pNumber){
//start eating if the adjacent philosophers aren't eating
if((state[(pNumber + 1) % 5] != EATING) && (state[(pNumber + 4) % 5] != EATING)){
state[pNumber] = EATING;
//signal self if test() called by another thread
pthread_cond_signal(&cond_var[pNumber]);
}
}
//used to make the philosopher's forks unavailable
void pickup_forks(int pNumber){
//get lock
pthread_mutex_lock(&mutex);
//set state to hungry
state[pNumber] = HUNGRY;
printf("Philosopher %d is HUNGRY\n", pNumber);
//attempt to begin eating. if unable to, will wait
test(pNumber);
while(state[pNumber] != EATING){
pthread_cond_wait(&cond_var[pNumber], &mutex);
//switched the order of the arguments
}
//release lock
pthread_mutex_unlock(&mutex);
}
//allow neighbors to use philosopher's forks
void release_forks(int pNumber){
//get lock
pthread_mutex_lock(&mutex);
//set own state to thinking
state[pNumber] = THINKING;
//tell adjacent philosophers to try to eat
test(((pNumber + 1) % 5));
test(((pNumber + 4) % 5));
//release lock
pthread_mutex_unlock(&mutex);
}
//used by the thread to run the philosophers
void *runPhilosopher(void *x){
//which philosopher it is
int pNumber = *((int*) x);
//initially thinking
state[pNumber] = THINKING;
printf("Philosopher %d is THINKING\n", pNumber);
//"think" for a random amount of time between 1-3 seconds
int sleepTime = rand() % 3 + 1;
sleep(sleepTime);
//each philosopher eats a total of 5 times
int i = 0;
for(i = 0; i < 5; i++){
//get the forks and begin eating
pickup_forks(pNumber);
//eating time
sleep(2);
//put down forks and resume thinking
release_forks(pNumber);
sleepTime = rand() % 3 + 1;
sleep(sleepTime);
}
printf("Philosopher %d has finished eating\n", pNumber);
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mutex, NULL);
int i = 0;
for(i = 0; i < 5; i++){
pthread_cond_init(&cond_var[i], NULL);
}
pthread_t tid[5]; //thread id
pthread_attr_t attr; //set of thread attributes
pthread_create(&tid[0], NULL, runPhilosopher, (void *) 0);
pthread_create(&tid[1], NULL, runPhilosopher, (void *) 1);
pthread_create(&tid[2], NULL, runPhilosopher, (void *) 2);
pthread_create(&tid[3], NULL, runPhilosopher, (void *) 3);
pthread_create(&tid[4], NULL, runPhilosopher, (void *) 4);
//wait for threads to finish
for(i = 0; i < 5; i++){
pthread_join(tid[i], NULL);
}
return 0;
}
我在使用 gedit 的 Linux 虚拟机上。该程序编译得很好,但是在尝试运行它时,我得到一个“分段错误”错误,这是来自尝试的线程创建,根据 gdb。我发现这里的相关问题都没有适用于我的程序。
我尝试过的事情:
- 注释掉绝大多数代码并尝试创建一个简单地运行 runPhilosopher 的线程,该线程已被剥离为仅一个 printf 语句。这导致代码似乎没有创建线程,因为没有输出。
- 用 &attr 替换线程创建中的 NULL。这将错误更改为已中止,但没有执行任何其他操作。
- 对所有这些都使用一个线程 ID,就像我在之前的程序中所做的那样。这没什么区别。
- 其他一些我不记得的零碎事情
是否有人看到了我忽略的简单解决方案,或者我的程序中是否存在严重缺陷?我无法理解问题可能是什么,但我完全承认我对 C 语言并不精通。任何帮助将不胜感激!
【问题讨论】:
标签: c linux multithreading pthreads