2009-05-14 18 views
17

he intentado hacer pasar una estructura que el cuarto argumento al utilizar pthread_create() con algo como esto:pasar estructuras como argumentos durante el uso de pthread_create()

pthread_create(&tid1, NULL, calca, &t); //t is the struct 

Ahora cada vez que intento acceder a las variables de la estructura - ta, tb o tc, sigo recibiendo un error: solicitud de miembro en algo que no es una estructura o unión.

¿Qué método alternativo podría usar para pasar estructuras al hilo?

Respuesta

24

Probablemente esté creando la estructura en el mismo ámbito que pthread_create. Esta estructura ya no será válida una vez que se abandone el alcance.

Intente crear un puntero a la estructura en el montón y pase ese puntero de estructura a su hilo. No olvides borrar ese recuerdo en algún lugar (en el hilo si nunca volverás a usarlo, o cuando ya no lo necesites).

Además, como se mencionó en cyberconte, si va a acceder a esa información desde diferentes subprocesos, deberá bloquear el acceso a ella con una exclusión mutua o sección crítica.

Editar 14 de mayo de 2009 a las 12:19 pm EST: Además, como han mencionado otras personas, debe convertir su parámetro al tipo correcto.

Si estás pasando una variable que es una estructura global (que usted parece estar insistiendo en), su función del hilo tendrá que echar al tipo:

void my_thread_func(void* arg){ 
    my_struct foo = *((my_struct*)(arg)); /* Cast the void* to our struct type */ 
    /* Access foo.a, foo.b, foo.c, etc. here */ 
} 

O, si estás de paso una Puntero a su estructura:

void my_thread_func(void* arg){ 
    my_struct* foo = (my_struct*)arg; /* Cast the void* to our struct type */ 
    /* Access foo->a, foo->b, foo->c, etc. here */ 
} 
+0

En realidad, creé el hilo en la función principal y creé la estructura justo después de incluir los archivos de encabezado. Entonces debe ser accesible para todas las funciones (corrígeme si estoy equivocado). – skinderneath

+0

Su edición reciente fue la publicación más útil aquí hasta ahora. Gracias. – skinderneath

+1

Gracias, esto me salvó el tocino. – g33kz0r

0

Puede utilizar la memoria compartida o una variable global (si nada más necesita ese argumento) o una lista vinculada si estos son hilos que se alimentan de datos.

Solo recuerda bloquear las variables que se están compartiendo.

Sin embargo, sin el código ofensivo actual, no puedo decirte lo que estás haciendo mal en tu implementación actual.

+0

Se eliminó el voto negativo debido a la expansión de la respuesta. –

2

Si está dentro de la función de subprocesos, el argumento que aprueba es nulo *. Tendrás que convertirlo en una estructura antes de poder usarlo como tal.

void my_thread_func(void* arg){ 
    my_struct foo = (my_struct)(*arg); /* Cast the void* to our struct type */ 
    /* Access foo.a, foo.b, foo.c, etc. here */ 
} 
+0

Lo hice pero ahora recibo un error de "eliminación de referencias" vacío 'puntero'. – skinderneath

+0

Harper destinado a escribir: my_struct foo = * (my_struct *) arg; o my_struct * foo = (my_struct *) arg; –

+0

Usó esta idea y la edición de Lyndsey Ferguson publicada - 14 de mayo de 2009 a las 12:19 PM EST. – skinderneath

0

Este mensaje de error significa que no está desreferenciando el puntero.

Estás diciendo "ta" en lugar de "t> a"

 
[[email protected] ~]$ cat testitx.c 
struct x { 
     int a, b; 
}; 

int main(int argc, char *argv[]) 
{ 
     struct x y, *z; 

     z = &y; 
     z.a = 10; 
} 
[[email protected] ~]$ cc -c testitx.c 
testitx.c: In function `main': 
testitx.c:10: error: request for member `a' in something not a structure or union 
[[email protected] ~]$ 
+0

No ayuda. Utilicé la solución de Harper Shelby para obtener un error de "desreferencia" vacío "puntero". – skinderneath

0

A menudo solía cometer los mismos errores que figuran en las otras respuestas, pero ahora tomo un enfoque ligeramente diferente que se mueve el potencial de error de la función de subprocesamiento a la llamada pthread_create.

Declaro y definir la función de enhebrado de una manera 'normal':

void *ThreadFunction(sPARAMETERS *Params) { 

    // do my threading stuff... 

} 

y cuando llamo pthread_create, necesito usar un yeso:

pthread_create(&ThreadId,0,(void*(*)(void*)) &ThreadFunction,&Params); 

casi nunca olvido use el & en los Params, y el compilador se encargará de cualquier error que yo haga en el otro extremo. Funciona muy bien para callbacks, también.

+0

Técnicamente hablando, este es un comportamiento indefinido, aunque en la mayoría de los compiladores funcionará para punteros de estructura ordinarios. No lo intentes con punteros de función de miembro de C++ ... – bdonlan

+0

No entiendo cómo esto ayuda a resolver mi problema. Esos moldes que has usado son demasiado crípticos. – skinderneath

1
  1. Crear un semáforo

  2. Crear otra estructura que consta de un puntero a la estructura y el mango de semáforos

  3. pasar un puntero a esta nueva estructura a pthread_create

  4. En el hilo padre, es decir, aquel llamado pthread_create, espera en el semáforo

  5. En el hilo hijo, copie los miembros de su estructura a las variables locales o guardarlos en otro lugar

  6. En el hilo hijo, la señal del semáforo

  7. En el hilo de los padres, cerrar el semáforo

0

my_struct foo = (my_struct) (* arg); es incoreect try my_struct * foo = (my_struct *) (arg);
Y, en la función Llamar al hilo, asegúrese de que sea estático (de modo que la memoria apuntada no se pierda en la niebla)

Cuestiones relacionadas