|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
[C/Unix]SIGSEGV su pthread_join()
Salve,
sono di nuovo alle prese con il threading in Unix. Probabilmente sono sfortunato, ma non funziona una cippa come dovrebbe. In questo caso, la chiamata a pthread_join fallisce miseramente con una SIGSEGV ogniqualvolta venga chiamata. Nel progetto wrappo la chiamata in questo modo: Codice:
int thread_join( int TID ) { DEBUG_ASSERT( TID != 0 ); return NOERROR( pthread_join( (pthread_t)TID, NULL ) ); } -i thread vengono fatti partire con successo -succede sia se sono in esecuzione, sia se sono in wait, sia se sono terminati -TID in ingresso è effettivamente il pthread_t restituito da pthread_create Però in _qualsiasi_ modo io chiami pthread_join, mi becco una SIGSEGV. Mistero ![]() ![]() EDIT: se chiamo pthread_join(0,0), inspiegabilmente, funziona. Quindi vuol dire che proprio quei TID che sto provando a chiamare io non sono validi... deve esserci un qualche errore alla creazione, perchè il thread viene creato ed è valido, ma il pthread_t ritornato no. Codice:
int thread_start( void(*runnableFunction)(void*), void* buf ) { int error; pthread_t TID; void*(*start_routine)(void*) = (void*(*)(void*))runnableFunction; DEBUG_ASSERT( runnableFunction ); error = pthread_create( &TID, NULL, start_routine, buf ); return (error==0) ? (int)TID : 0; } Ultima modifica di Tommo : 23-12-2010 alle 18:36. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Qualcuno mi salvi!
![]() Non riesco a trovare il modo di farlo andare... mi andrebbe bene anche un link ad un forum internazionale più adeguato a questi argomenti! Non fatemi scomodare il prof ![]() |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
boh di certo non capisco perché usi int invece di pthread_t, sei così sicuro che pthread_t sia definito come int? cercando in giro non ho trovato molto, solo questo in cui è definito come unsigned long (questo spiegherebbe perché il valore che ritorni non è valido)
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Sono convinto anche io che il problema stia nel fatto che mescoli pthread_t ed int.
In particolare e' facile che in una macchina a 64 bit quel pthread_t sia a 64 bit, con tutte le conseguenze del caso. Non mescolare, hai alternative piu' sane a disposizione che non ritornare uno 0 in caso di fallimento, come lanciare un'eccezione, ritornare un puntatore a un pthread_t o ritornare solo lo stato di errore (come fa pthread_create) ed accettare il pthread_t come argomento.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
uhm... faccio il cast ad int per una questione di compatibilità: la stessa funzione su Win32 fa un cast di una HANDLE.
int agisce da "contenitore opaco" rispetto all'user, che lo può usare come identificatore. Quindi -non posso lanciare un'eccezione (C liscio) -non posso parlare esplicitamente di pthread_t Però se è vero che il problema è il tipo di dato, potrei definire un tipo thread_t definito come pthread_t su Unix e come HANDLE su Win32. Oppure usare long invece che int, così se ne occupa direttamente il compilatore. Alla fine mi sembra sia la cosa più sana. EDIT: usando "#define thread_t unsigned long" funziona alla perfezione su tutti i SO, grazie mille ![]() Il problema era molto più stupido del previsto ![]() |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
ancora però, sei sicuro che sia generico a sufficienza? io fossi in te, se dovessi fare una qualche sorta di libreria cross platform per i thread userei una struttura dati che mappi il tipo del thread id con un intero, tipo map<int, pthread_t (o HANDLE)> per dirlo in termini di c++
così puoi rifarti alla definizione di pthread_t e HANDLE e usare un tuo tipo come "handle" Ultima modifica di tuccio` : 27-12-2010 alle 15:58. |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Sicuramente si, sarebbe la cosa migliore... sicuramente in C++, dove è più gestibile, l'avrei fatto.. in è più difficile da mantenere.
E poi col "rischio" tutto si riduce a un cast, mentre con le strutture dati ho anche un costo di ricerca ![]() |
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
[/quote]
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Quote:
Quindi se creo pthread_t[100] quello è grosso 800b su architetture x64, ma HANDLE[100] è sempre grosso 400 perchè è proprio un'int. E questo può generare dei comportamenti imprevedibili lato utente che con long mi risparmio. Tanto sprecare 4 byte su un'handle non credo proprio che sia un problema. |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
credo che voglia dire una cosa tipo
typedef pthread_t mythread_t; su linux e typedef HANDLE mythread_t; su windows e thread_join ritorna un mythread_t invece di un unsigned int in entrambi i casi |
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
Codice:
typedef union { #if defined(WIN32) /* o _WIN32 ? Non ricordo :D */ HANDLE handle; #elif defined(__unix__) /* Non standard, ma non ricordo la macro corretta... :P */ pthread_t handle; #endif char _filler[8]; } mythread_t;
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 21:52.