我正在尝试使用pthreads,互斥锁和条件变量在C中实现哲学家用餐问题。
- 它需要一个命令行参数来指定程序应该运行多长时间。我必须使用睡眠功能来实现这一点。
- 每个哲学家最多可以吃10顿饭。一旦他们达到10餐,pthread应该终止。
- 在设定的时间结束时,pthreads需要终止,并且应该打印每个哲学家吃的饭的数量。
我的输出有一些问题:
1.让main函数按照命令行中输入的秒数休眠,似乎不会使输出有什么不同。
1.大多数哲学家在程序的大多数执行中挨饿。
1.当我打印出一个哲学家在思考或吃饭时,一个“哲学家5”出现了,尽管应该只有哲学家0-4。
我的代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
//Function declarations
void *pickup_forks(void * philosopher_number);
void *return_forks(void * philosopher_number);
void test(int philosopher_number);
int left_neighbor(int philosopher_number);
int right_neighbor(int philosopher_number);
double think_eat_time(void);
void think(double think_time);
void eat(double eat_time);
//Constants to be used in the program.
#define PHILOSOPHER_NUM 5
#define MAX_MEALS 10
#define MAX_THINK_EAT_SEC 3
//States of philosophers.
enum {THINKING, HUNGRY, EATING} state[PHILOSOPHER_NUM];
//Array to hold the thread identifiers.
pthread_t philos_thread_ids[PHILOSOPHER_NUM];
//Mutex lock.
pthread_mutex_t mutex;
//Condition variables.
pthread_cond_t cond_vars[PHILOSOPHER_NUM];
//Array to hold the number of meals eaten for each philosopher.
int meals_eaten[PHILOSOPHER_NUM];
int main(int argc, char *argv[])
{
//Ensure correct number of command line arguments.
if(argc != 2)
{
printf("Please ensure that the command line argument 'run_time' is passed.\n");
}
else
{
//Set command line argument value to variable run_time;
double run_time = atof(argv[1]);
//Initialize arrays.
int i;
for(i = 0; i < PHILOSOPHER_NUM; i++)
{
state[i] = THINKING;
pthread_cond_init(&cond_vars[i], NULL);
meals_eaten[i] = 0;
}
//Initialize the mutex lock.
pthread_mutex_init(&mutex, NULL);
//Join the threads.
for(i = 0; i < PHILOSOPHER_NUM; i++)
{
pthread_join(philos_thread_ids[i], NULL);
}
//Create threads for the philosophers.
for(i = 0; i < PHILOSOPHER_NUM; i++)
{
pthread_create(&philos_thread_ids[i], NULL, pickup_forks, (void *)&i);
}
sleep(run_time);
for(i = 0; i < PHILOSOPHER_NUM; i++)
{
pthread_cancel(philos_thread_ids[i]);
}
//Print the number of meals that each philosopher ate.
for(i = 0; i < PHILOSOPHER_NUM; i++)
{
printf("Philosopher %d: %d meals\n", i, meals_eaten[i]);
}
}
return 0;
}
void *pickup_forks(void * philosopher_number)
{
int loop_iterations = 0;
int pnum = *(int *)philosopher_number;
while(meals_eaten[pnum] < MAX_MEALS)
{
printf("Philosoper %d is thinking.\n", pnum);
think(think_eat_time());
pthread_mutex_lock(&mutex);
state[pnum] = HUNGRY;
test(pnum);
while(state[pnum] != EATING)
{
pthread_cond_wait(&cond_vars[pnum], &mutex);
}
pthread_mutex_unlock(&mutex);
(meals_eaten[pnum])++;
printf("Philosoper %d is eating meal %d.\n", pnum, meals_eaten[pnum]);
eat(think_eat_time());
return_forks((philosopher_number));
loop_iterations++;
}
}
void *return_forks(void * philosopher_number)
{
pthread_mutex_lock(&mutex);
int pnum = *(int *)philosopher_number;
state[pnum] = THINKING;
test(left_neighbor(pnum));
test(right_neighbor(pnum));
pthread_mutex_unlock(&mutex);
}
int left_neighbor(int philosopher_number)
{
return ((philosopher_number + (PHILOSOPHER_NUM - 1)) % 5);
}
int right_neighbor(int philosopher_number)
{
return ((philosopher_number + 1) % 5);
}
void test(int philosopher_number)
{
if((state[left_neighbor(philosopher_number)] != EATING) &&
(state[philosopher_number] == HUNGRY) &&
(state[right_neighbor(philosopher_number)] != EATING))
{
state[philosopher_number] = EATING;
pthread_cond_signal(&cond_vars[philosopher_number]);
}
}
double think_eat_time(void)
{
return ((double)rand() * (MAX_THINK_EAT_SEC - 1)) / (double)RAND_MAX + 1;
}
void think(double think_time)
{
sleep(think_time);
}
void eat(double eat_time)
{
sleep(eat_time);
}
以下是使用10秒的输出:
~$ gcc dining_philos.c -o dp -lpthread
~$ ./dp 10
Philosoper 1 is thinking.
Philosoper 2 is thinking.
Philosoper 3 is thinking.
Philosoper 4 is thinking.
Philosoper 5 is thinking.
Philosoper 2 is eating meal 1.
Philosoper 4 is eating meal 1.
Philosoper 2 is thinking.
Philosoper 4 is thinking.
Philosoper 2 is eating meal 2.
Philosoper 4 is eating meal 4.
Philosoper 4 is thinking.
Philosoper 2 is thinking.
Philosoper 2 is eating meal 3.
Philosoper 4 is eating meal 5.
Philosoper 2 is thinking.
Philosoper 4 is thinking.
Philosopher 0: 2 meals
Philosopher 1: 0 meals
Philosopher 2: 3 meals
Philosopher 3: 0 meals
Philosopher 4: 5 meals
”我会感激任何帮助。谢谢!**
2条答案
按热度按时间wfveoks01#
pthread_create传递一个指针作为它的最后一个参数。该指针必须在线程运行时有效,而不仅仅是在创建线程时有效。你正在使用一个指向循环变量i的指针,它已经蒸发了。
同样不确定为什么在pthread_create之前调用pthread_join,但我希望它返回错误(您没有检查)。
5fjcxozz2#
我有点晚了,但为以后的参考3。问题的发生是因为你在创建哲学家时丢失了数据。尝试制作数组和发送数组数据地址,问题解决