called object ‘waitsem’ is not a function or function pointer waitsem(chopstick[(i+1)%5]); ^ zhexuejia1.c:40:11: 附注:在此声明 sem_t waitsem,signalsem;
时间: 2024-04-28 07:19:12 浏览: 9
这个错误通常是因为您试图将一个信号量 `waitsem` 当作函数或函数指针来调用。请确保在代码中正确地使用了信号量,而不是试图将其作为函数调用。例如,在使用 `waitsem` 等待一个信号量时,应该使用 `sem_wait(&waitsem)` 而不是 `waitsem()`。
如果您仍然遇到这个错误,请检查您的代码,并确保您正确地声明和初始化了信号量。请注意,信号量是一种特殊类型的变量,不能像函数一样调用。
相关问题
#include "mysemop.h" #include "philosopher.h" #include <unistd.h> #include <sys/types.h> void philosopher(int i); // the array and the variable below storage their sem_id int chopsticks[5]; int main(int argc, char * args[]) { for (int i = 0; i < 5; ++i) chopsticks[i] = CreateSem(1); int fpid = 1; int amount = 5; while (fpid != 0 && --amount) fpid = fork(); philosopher(amount); return 0; } void philosopher(int i) { printf("my i = %d\n", i); while (true) { think(i); // for each philosopher, the i-th chopstick is at his left, // and the (i + 1) % 5 th chopstick is at his right; // odd get left first, and even get right first if (i % 2 == 1) { Psem(chopsticks[i]); printf("philosopher %d get left\n", i); Psem(chopsticks[(i + 1) % 5]); printf("philosopher %d get right\n", i); eat(i); Vsem(chopsticks[i]); printf("philosopher %d put down left\n", i); Vsem(chopsticks[(i + 1) % 5]); printf("philosopher %d put down right\n", i); } else { Psem(chopsticks[(i + 1) % 5]); printf("philosopher %d get right\n", i); Psem(chopsticks[i]); printf("philosopher %d get left\n", i); eat(i); Vsem(chopsticks[(i + 1) % 5]); printf("philosopher %d put down right\n", i); Vsem(chopsticks[i]); printf("philosopher %d put down left\n", i); } } }细致解读这段代码
这段代码实现了哲学家就餐问题的解决方案。首先在main函数中创建了5个互斥信号量 chopsticks[i],每个信号量的初值为1。然后通过fork函数创建了5个子进程,每个子进程都调用 philosopher 函数进行操作。
philosopher 函数中首先进行思考(调用 think 函数),然后根据奇偶性分别获取左边或右边的筷子。如果是奇数哲学家,则先获取左边的筷子,再获取右边的筷子;如果是偶数哲学家,则先获取右边的筷子,再获取左边的筷子。
获取筷子的过程通过 Psem 函数来进行,即将信号量的值减1,如果信号量的值小于0,则进程被阻塞。当哲学家获取到两支筷子后,调用 eat 函数进行进餐,然后通过 Vsem 函数将两支筷子放回桌子上,并将信号量的值加1,唤醒其他等待的进程。
整个过程中需要注意死锁问题,即当所有哲学家都只拿到了一支筷子时,无法进行进餐,形成死锁。解决方案可以通过协议来规定哲学家拿筷子的顺序,避免死锁的产生。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h> #include <time.h> #define N 5 pthread_mutex_t chopstick[N];//筷子信号量 //哲学家线程函数 void* philosopher(void* arg){ int *i; i = (int *)arg;//哲学家序号 for(;;){ //思考 printf("%d 号哲学家在思考......\n",*i); sleep(rand()%3);//休眠随机时间,不超过3秒 //尝试取回左右两边的筷子 if(pthread_mutex_trylock(&chopstick[*i]) == 0 && pthread_mutex_trylock(&chopstick[(*i+1)%N]) == 0)//尝试同时拿到两个筷子 { //成功拿到两个筷子 printf("%d号哲学家在进餐......\n",*i); sleep(rand()%3);//休眠随机时间,不超过3秒 //放回筷子 pthread_mutex_unlock(&chopstick[*i]); pthread_mutex_unlock(&chopstick[(*i+1)%N]); } else { //释放已拿到的筷子,等待随机时间后重试 pthread_mutex_unlock(&chopstick[*i]); pthread_mutex_unlock(&chopstick[(*i+1)%N]); sleep(rand()%2); } } } int main(){ pthread_t id[N]; int i; for(i=0;i<N;i++) pthread_mutex_init(&chopstick[i],NULL); for(i=0;i<N;i++) { int *p; p=malloc(sizeof(int)); *p=i; pthread_create(&id[i],NULL,philosopher,(void*)p); } for(i=0;i<N;i++) pthread_join(id[i],NULL); }给代码加注释
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#define N 5 //哲学家数量
pthread_mutex_t chopstick[N]; //筷子信号量
//哲学家线程函数
void* philosopher(void* arg){
int *i;
i = (int *)arg; //哲学家序号
for(;;){
//思考
printf("%d 号哲学家在思考......\n",*i);
sleep(rand()%3); //休眠随机时间,不超过3秒
//尝试取回左右两边的筷子
if(pthread_mutex_trylock(&chopstick[*i]) == 0 && pthread_mutex_trylock(&chopstick[(*i+1)%N]) == 0) //尝试同时拿到两个筷子
{
//成功拿到两个筷子
printf("%d号哲学家在进餐......\n",*i);
sleep(rand()%3); //休眠随机时间,不超过3秒
//放回筷子
pthread_mutex_unlock(&chopstick[*i]);
pthread_mutex_unlock(&chopstick[(*i+1)%N]);
}
else
{
//释放已拿到的筷子,等待随机时间后重试
pthread_mutex_unlock(&chopstick[*i]);
pthread_mutex_unlock(&chopstick[(*i+1)%N]);
sleep(rand()%2);
}
}
}
int main(){
pthread_t id[N];
int i;
//初始化筷子信号量
for(i=0;i<N;i++)
pthread_mutex_init(&chopstick[i],NULL);
//创建哲学家线程
for(i=0;i<N;i++)
{
int *p;
p=malloc(sizeof(int));
*p=i;
pthread_create(&id[i],NULL,philosopher,(void*)p);
}
//等待哲学家线程结束
for(i=0;i<N;i++)
pthread_join(id[i],NULL);
}
```
代码中实现了哲学家问题的解决方案,通过线程模拟哲学家的行为,使用互斥锁来解决筷子竞争的问题。其中,`pthread_mutex_init`用于初始化互斥锁,`pthread_create`用于创建线程,`pthread_join`用于等待线程结束。对于每一个哲学家线程,其会进入一个无限循环,先进行思考,然后尝试取回左右两边的筷子,如果成功则进餐,否则释放已拿到的筷子并等待随机时间后重试。