pthread crear y pasar un entero como último argumento
Tengo las siguientes funciones:
void *foo(void *i) {
int a = (int) i;
}
int main() {
pthread_t thread;
int i;
pthread_create(&thread, 0, foo, (void *) i);
}
En la compilación, hay algunos errores sobre el casting ((void *) i
y int a = (int) i
). ¿Cómo puedo pasar un entero como el último argumento de pthread_create
correctamente?
5 answers
Basándose en la respuesta de szx (así que dale el crédito), así es como funcionaría en tu for
bucle:
void *foo(void *i) {
int a = *((int *) i);
free(i);
}
int main() {
pthread_t thread;
for ( int i = 0; i < 10; ++1 ) {
int *arg = malloc(sizeof(*arg));
if ( arg == NULL ) {
fprintf(stderr, "Couldn't allocate memory for thread arg.\n");
exit(EXIT_FAILURE);
}
*arg = i;
pthread_create(&thread, 0, foo, arg);
}
/* Wait for threads, etc */
return 0;
}
En cada iteración del bucle, estás asignando nueva memoria, cada una con una dirección diferente, por lo que lo que se pasa a pthread_create()
en cada iteración es diferente, por lo que ninguno de tus subprocesos termina tratando de acceder a la misma memoria y no obtienes ningún problema de seguridad de subprocesos de la forma en que lo harías si acabas de pasar la dirección de i
. En este caso, también podría configurar un array y pasa las direcciones de los elementos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-08 00:05:41
Puede asignar un int
en el montón y pasarlo a pthread_create()
. Luego puede desasignar en su hilo de función:
void *foo(void *i) {
int a = *((int *) i);
free(i);
}
int main() {
pthread_t thread;
int *i = malloc(sizeof(*i));
pthread_create(&thread, 0, foo, (void *) i);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-07 19:31:22
Deberías convertir la dirección de i
(en lugar del valor de i
como lo haces ahora) en el último argumento de pthread_create().
pthread_create(&thread, 0, foo, (void *) &i);
^ is missing
Y el casting también está mal en tu función. Debe ser:
int a = *((int*) i);
- Si quieres leer el valor, también debes inicializar
i
a algún valor en main() ya que ahora no está inicializado.
2 Use la definición apropiada para main ():
int main(void)
O int main(int argc, char *argv[])
o su equivalente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-07 19:47:18
Vieja pregunta, pero me enfrenté al mismo problema hoy, y decidí no seguir este camino.
Mi aplicación era realmente sobre el rendimiento, así que elegí tener este array de int
s declarado estáticamente.
Ya que no conozco un montón de aplicaciones donde su pthread_join
/ pthread_cancel
está en otro ámbito que su pthread_create
, elegí este camino:
#define NB_THREADS 4
void *job(void *_i) {
unsigned int i = *((unsigned int *) _i);
}
int main () {
unsigned int ints[NB_THREADS];
pthread_t threads[NB_THREADS];
for (unsigned int i = 0; i < NB_THREADS; ++i) {
ints[i] = i;
pthread_create(&threads[i], NULL, job, &ints[i]);
}
}
Lo encuentro más elegante, más eficiente, y no tienes que preocuparte por liberarte ya que solo vive en este ámbito.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-16 22:22:50
Si bien esta es una pregunta antigua, falta una opción cuando todo lo que necesita es pasar un entero positivo como un descriptor: puede pasarlo directamente como la dirección, mientras que es un truco funciona bien y evita asignar nada :)
NOTA: el tamaño del entero debe coincidir con el tamaño de un puntero en su sistema operativo, pero hoy en día la mayoría de los sistemas son 64bits nativos.
#include <pthread.h>
#include <inttypes.h>
#include <stdio.h>
void *_thread_loop(void *p)
{
uint64_t n = (uint64_t)p;
printf("received %llu\n", n);
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t read_thread_id;
uint64_t n = 42;
pthread_create(&read_thread_id, NULL, _thread_loop, (void *)n);
pthread_join(read_thread_id, NULL);
return 0;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 07:30:27