我在Ubuntu上运行算法时有点头疼。它似乎在Windows上运行得很好(Dev C ++或CodeBlocks),但当我尝试在Geany上运行它时,我一直收到错误:
Filosofos.cpp:144:11: error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’ [-fpermissive]
它突出显示该区域为错误:
iret1 = pthread_create(&thread1, NULL, (void *)philosopher, (int*)p[1]);
根据我的研究,我尝试更改为long int
,long long
- 但没有成功。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
#include <string.h>
#include <ctype.h>
#include <semaphore.h>
#define N 5 /* amount of philosophers*/
#define LEFT (i+N-1)%N/* left neighbor i */
#define RIGHT (i+1)%N /* right neighbor i */
#define THINKING 0 /* philosopher thinking */
#define HUNGRY 1 /* philosopher tries to catch the fork */
#define EATING 2 /* philosopher eating */
#define TRUE 1
sem_t s[N]; //one semaphore for each philosopher
sem_t mutex;
int state[N];
//array to control philosophers state
pthread_t thread1, thread2, thread3, thread4, thread5;
//one thread for each philosopher
void take_forks(int i);
void put_forks(int i);
void test(int i);
void think(int i);
void eat(int i);
/* i: number of the philosopher, from 0 to N-1 */
void philosopher(int i) {
while (TRUE) {
think(i); /
take_forks(i); /* take two forks or block it */
eat(i);
put_forks(i);
}
}
void take_forks(int i) {
sem_wait(&mutex); //down(&mutex); /* entra na regiao critica */
state[i] = HUNGRY; /* change the state to hungry */
printf("philosopher %d HUNGRY\n",i);
test(i); /* try to catch two forks */
sem_post (&mutex); // up(&mutex); /* get out the critical region*/
sem_wait(&s[i]); // down(&s[i]); /* block if the forks are not available */
}
void put_forks(int i) {
sem_wait(&mutex); // down(&mutex); /* get in the critical region */
state[i] = THINKING; /* Philosopher has ended eating */
printf("philosopher %d THINKING\n",i);
test(LEFT); /* check if the left neighbor can eat now */
test(RIGHT); /* check if the right neighbor can eat now */
sem_post(&mutex); // up(&mutex); /* get out of the critical region*/
}
void test(int i) { //test if the philosopher´s neighbors can eat
if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) {
state[i] = EATING;
printf("philosopher %d EATING\n",i);
sem_post(&s[i]); //up(&s[i]);
}
}
void think(int i) {
sleep(rand() % 10 + 1);
return;
}
void eat(int i) {
sleep(rand() % 10 + 1);
return;
}
////////////// MAIN FUNCTION////////////////////////
int main (int argc, char *argv[])
{
int iret1, iret2, iret3, iret4, iret5;
int i;
int p[N] ;
int sem_init(sem_t *sem, int pshared, unsigned int value);
for (i= 0; i < N ;i++ ) {
sem_init(&s[i], 0, 1);
p[i] = i;
}
sem_init(&mutex, 0, 1);
iret1 = pthread_create(&thread1, NULL, (void *) philosopher, (int *) p[1]);
iret2 = pthread_create(&thread2, NULL, (void *) philosopher, (int *) p[2]);
iret3 = pthread_create(&thread3, NULL, (void *) philosopher, (int *) p[3]);
iret4 = pthread_create(&thread4, NULL, (void *) philosopher, (int *) p[4]);
iret5 = pthread_create(&thread5, NULL, (void *) philosopher, (int *) p[0]);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
pthread_join(thread4, NULL);
pthread_join(thread5, NULL);
exit(0);
}
答案 0 :(得分:4)
线程启动功能的类型应为
void *(*)(void *);
所以,philosopher()
需要更改为
void *philosopher(void *data)
{
int i = *(int *) data;
// The rest of the function
}
然后在main()
for (int i = 0; i < N; ++i) {
pthread_create(&thread[i], NULL, philosopher, &p[i]);
}
for
循环在这里是为了避免重复相同的代码,坚持DRY原则,因为如果你不这样做,那么维护你的代码将变得不可能。
这是您的代码,但已修复和改进,特别是可读性。我希望更多的程序员重视可读性,因为阅读代码是我们最常做的,我们阅读的内容比编写的要多得多
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define N 5 /* amount of philosophers */
#define LEFT (i + N - 1) % N /* left neighbor i */
#define RIGHT (i + 1) % N /* right neighbor i */
#define THINKING 0 /* philosopher thinking */
#define HUNGRY 1 /* philosopher tries to catch the fork */
#define EATING 2 /* philosopher eating */
#define TRUE 1
sem_t s[N]; // one semaphore for each philosopher
sem_t mutex;
int state[N];
void take_forks(int i);
void put_forks(int i);
void test(int i);
void think(int i);
void eat(int i);
void *
philosopher(void *data)
{
int i = *(int *) data;
while (TRUE) {
think(i);
take_forks(i); /* take two forks or block it */
eat(i);
put_forks(i);
}
}
void
take_forks(int i)
{
sem_wait(&mutex);
state[i] = HUNGRY;
printf("philosopher %d HUNGRY\n", i);
test(i); /* try to catch two forks */
sem_post (&mutex);
sem_wait(&s[i]);
}
void
put_forks(int i)
{
sem_wait(&mutex);
state[i] = THINKING;
printf("philosopher %d THINKING\n", i);
test(LEFT); /* check if the left neighbor can eat now */
test(RIGHT); /* check if the right neighbor can eat now */
sem_post(&mutex);
}
void
test(int i)
{
if ((state[i] == HUNGRY) && (state[LEFT] != EATING) && (state[RIGHT] != EATING)) {
state[i] = EATING;
printf("philosopher %d EATING\n", i);
sem_post(&s[i]);
}
}
void
think(int i)
{
sleep(rand() % 10 + 1);
return;
}
void
eat(int i)
{
sleep(rand() % 10 + 1);
return;
}
int
main(int argc, char *argv[])
{
int i;
pthread_t thread[N];
int p[N];
int sem_init(sem_t *sem, int pshared, unsigned int value);
for (i= 0; i < N ;i++ ) {
sem_init(&s[i], 0, 1);
p[i] = i;
}
sem_init(&mutex, 0, 1);
for (int i = 0; i < N; ++i)
pthread_create(&thread[i], NULL, philosopher, &p[i]);
for (int i = 0; i < N; ++i)
pthread_join(thread[i], NULL);
return 0;
}
不要使用评论,说出像
这样非常明确的内容state = NEW_STATE; // Change the state to NEW_STATE