您的台词如下:
arg_l[0] = int A;
完全坏掉了。你会侥幸逃脱:
int A = ((int *)arg_l)[0];
您不能有效地取消引用 void *,也不能索引它们(部分原因是需要取消引用,部分原因是在标准 C 中——与 GNU C 相对——sizeof(void) 未定义)。如图所示,您需要通过强制转换然后解除引用来转换为适当的类型。
注意:args[2] = phil_num[i]; 写入越界(您定义了int args[2];,但看起来您需要int args[3];。
您必须为每个哲学家传递一个单独的数组,因为不能保证给定线程在主线程重新分配新值之前已经读取了信息。通常,您将使用结构而不是数组来传递给单个线程的数据;你有一个这些结构的初始化数组,以便每个线程都有自己独特的控制信息。
有什么方法可以举个例子吗?
有点像这样。关键是struct Info的数组,每个都单独初始化(使用C99复合字面量),并将数组的不同元素传递给每个线程,以便它获取自己的数据,而不是试图共享数据与其他线程。
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
struct Info
{
int number;
int turns;
int diner;
};
enum { MAX_PHILOSOPHERS = 10 };
enum { MAX_TURNS = 99 };
static sem_t mutex;
static sem_t S[MAX_PHILOSOPHERS];
static void *philosopher(void *arg_l);
int main(void)
{
int A, B;
printf("How many philosophers? How many turns? ");
fflush(stdout);
if (scanf("%d %d", &A, &B) != 2)
{
fprintf(stderr, "Failed to read input\n");
return 1;
}
if (A < 2)
fprintf(stderr, "You specified too few philosophers (%d)\n", A);
if (A > MAX_PHILOSOPHERS)
fprintf(stderr, "You specified too many philosophers (%d, but the maximum is %d)\n",
A, MAX_PHILOSOPHERS);
if (B < 1)
fprintf(stderr, "You specified too few turns (%d)\n", B);
if (B > MAX_TURNS)
fprintf(stderr, "You specified too many turns (%d, but the maximum is %d)\n",
B, MAX_TURNS);
if (A < 2 || A > MAX_PHILOSOPHERS || B < 1 || B > MAX_TURNS)
return 1;
printf("You have %d philosophers who get %d turns each\n", A, B);
/* This assignment could be in the thread creation loop before pthread_create() */
/* Or in the loop that uses sem_init() */
struct Info info[A];
for (int i = 0; i < A; i++)
info[i] = (struct Info){ A, B, i};
sem_init(&mutex, 0, 1);
for (int i = 0; i < A; i++)
sem_init(&S[i], 0, 0);
pthread_t thread_id[A];
for (int i = 0; i < A; i++)
{
pthread_create(&thread_id[i], NULL, philosopher, &info[i]);
printf("Philosopher %d is thinking\n", i + 1);
}
for (int i = 0; i < A; i++)
pthread_join(thread_id[i], NULL);
printf("Dinner is over\n");
return 0;
}
static void *philosopher(void *arg_l)
{
struct Info *info = arg_l;
printf("N = %d, T = %d, I = %d\n", info->number, info->turns, info->diner);
/* ...do dining stuff; remember to share nicely!... */
return 0;
}
#pragma 允许代码在 macOS Sierra 上编译,它没有 <semaphore.h> 函数的工作版本——它们只是返回错误指示并将 errno 设置为 ENOSYS(函数未实现) .
这段代码还应该检查 pthread 函数和信号量操作的返回值——不这样做就是懒惰。