您好我的代码中存在下一个问题:
"从不同大小的整数转换为指针-wint-to-pointer-cast"
此问题出在此行代码中
pthread_create(&filos[i], NULL, (void *)filosofos,(void *) i);
特别是在(void *)i
中#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#define N 5 //num. de filosofos
#define IZQ (i-1)%N //vecino izquierdo de i
#define DER (i+1)%N //vecino derecho de i
#define PENSANDO 0
#define CON_HAMBRE 1
#define COME 2
pthread_t filos[N]; //hilos que representan a los filósofos
sem_t mutex ; //semáforo para la sección crítica
sem_t s[N]; //semáforos para los filósofos
int estado [N] ; //estado actual de cada filósosfo
/*
el filosofo i va a perder el tiempo... (va a pensar)
*/
void pensar (int i)
{
int t ;
t = rand() % 11;
printf("Filosofo %d pensando \n", i) ;
estado[i] = PENSANDO;
sleep (t) ;
}
/*
El filosofo i, va a comer !!!!!!!!
*/
void comer (int i)
{
printf("Filósofo %d esta comiendo un caballo \n", i);
estado[i] = COME;
sleep (5);
}
/*
Verifica que pueda tomar ambos tenedores
*/
void verifica(int i)
{
if( estado[i]==CON_HAMBRE && estado[IZQ]!=COME && estado[DER]!=COME ){
estado[i] = COME;
printf("Filósofo %d comiendo\n", i) ;
sem_post(&s[i]);
}
}
/*
El filosofo i intenta tomar los tenedores
*/
void toma_tndrs(int i)
{
sem_wait(&mutex); //entra a la sección crítica, hace uso del semaforo
estado[i] = CON_HAMBRE; //dice: tengo mucha hambre!!!!!!!!!!
verifica(i); // verifica que pueda tomar los tenedores
sem_post(&mutex); //sale de la sección crítica y el sem. puede permitir la entrada a alguien más
sem_wait(&s[i]); //se bloquea si no consiguió los tenedores
}
/*
el filosofo i dejará los tenedores
*/
void deja_tndrs(int i)
{
sem_wait(&mutex); // de nuevo entra a la sección critica
estado[i] = PENSANDO; //deja de comer y se pone a pensar
verifica(IZQ);
verifica(DER);
sem_post(&mutex);
}
/*
*/
void * filosofos (int i)
{
int j ;
for (; ; )
{
pensar(i) ;
toma_tndrs(i) ;
comer(i) ;
deja_tndrs(i) ;
}
}
main()
{
int i ;
for(i = 0; i < 5; i++){
sem_init (&s[i], 0, 1);
estado[i] = PENSANDO ;
}
sem_init (&mutex, 0, 1);
//creamos un hilo de ejecucion para cada filosofo, que ejecuta filosofos()
for (i=0; i<N; i++)
pthread_create(&filos[i], NULL, (void *)filosofos,(void *) i);
//cada hilo espera a que terminen los demás y libera los recursos
for (i=0; i<N; i++){
pthread_join(filos[i],NULL);
}
}
答案 0 :(得分:3)
假设它是导致问题的i
变量的强制转换,首先将其强制转换为大于int
的整数类型,同时大到足以容纳指针。
一种这样的类型,设计用于足够大以容纳任何整数或指针的目的,是intptr_t
,例如在{1}中描述。 this fixed-width integer reference
演员表看起来像
(void *) (intptr_t) i
在线程函数中,您执行相反的操作,首先转换为intptr_t
,然后转换为int
。
void * filosofos (void *p)
{
int i = (int) (intptr_t) p;
...
return NULL;
}
请注意,我更改了线程函数的签名是正确的,它需要一个void *
参数,这对sizeof(int) != sizeof(void *)
的系统产生了很大的影响,这在您的系统中似乎是正确的案件。另请注意,我在函数末尾返回NULL
。那是因为声明(并指定)线程函数以返回指针。不从声明的函数返回值会导致未定义的行为。
对于那些好奇的人,虽然我通常不会建议将一个整数强制转换为这样的指针,但是所有内容都有例外情况,这是少数情况下(如果不是唯一一个)可以接受的情况之一。< / p>
许多人仍然看不起这样的解决方案,但仍然使用它,因为它比整个malloc
- 复制 - free
马戏团更容易,否则需要。
对值使用动态分配内存的解决方案如下所示:
线程创建
// Allocate memory for the index
int *p = malloc(sizeof i);
if (p == NULL)
{
// TOOD: Handle error! (Left as an exercise to the reader)
}
// Copy the value
*p = i;
// And create the thread
pthread_create(&filos[i], NULL, &filosofos, p); // Note: no cast needed
在线程函数
中void * filosofos (void *p)
{
int i = *(int *) p;
free(p);
...
return NULL;
}
虽然这种解决方案更“正确”,但它的可读性更低,这意味着它的可维护性更低;它有更多的代码,这意味着更多的错误机会;如果free
调用被遗忘(迟早会发生 ),它可能会导致内存泄漏。
答案 1 :(得分:0)
您正在将i
转换为void指针而不创建对它的引用。我不是西班牙语演讲者,但我可以假设你有意这样做:
pthread_create(&filos[i], NULL, (void *)filosofos, (void *)&i);
否则,您已经创建了对内存地址i
的引用,并且在内存中没有任何内容可以触及这么低的地址:P
此外,明确地向和从void指针进行强制转换是一件值得避免的事情。
https://www.tutorialspoint.com/cprogramming/c_pointers.htm
尝试更多地了解指针。