|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
[C/Unix]errore EINTR su semop()
Salve,
sto sviluppando una stramaledett* tesina su Unix, e mi trovo a combattere con i semafori. Apparentemente per nessun motivo, quando chiamo semop() (tutte le volte) la chiamata fallisce con errore EINTR, o "Interruption during the execution of the syscall". Nello specifico succede quando chiamo per la prima volta sem_wait() dopo la creazione del semaforo. Ovviamente trattandosi di Unix non è stato possibile trovare documentazione su questo comportamento, quindi chiedo lumi ![]() Il codice è questo qua, trattasi di un thin-wrapper per la portabilità (le stesse funzioni le ho implementate anche su win32) Codice:
#ifdef _DEBUG #define NOERROR( T ) _noerror( T, __FUNCTION__, __LINE__ ) #else #define NOERROR( T ) (T==ERROR ? ERROR : 1) #endif int _noerror( int e, const char* func, int line ) { if( e == ERROR ) { printf( "Error at %d:%s() \"%s\"\n", line, func, strerror( errno ) ); DEBUG_ASSERT(0); return ERROR; } return 1; } int sem_create( int amount ) { int s; DEBUG_ASSERT( amount >= 0 ); s = semget( IPC_PRIVATE, 1, 0666 | IPC_CREAT | IPC_EXCL ); //1 solo semaforo //inizializza il semaforo a "amount" per simulare il comportamento Win32 if( NOERROR( s ) && NOERROR( semctl( s, 0, SETVAL, amount ) ) ) return s; return -1; } int sem_op( int SID, int op ) { struct sembuf oper; DEBUG_ASSERT( SID > 0 ); oper.sem_num = 0; oper.sem_op = op; oper.sem_flg = 0; return NOERROR( semop( SID, &oper, 1 ) ); } int sem_wait( int SID ) { return sem_op( SID, -1 ); } int sem_signal( int SID ) { return sem_op( SID, 1 ); } Ultima modifica di Tommo : 18-12-2010 alle 19:17. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Mar 2005
Città: ~
Messaggi: 740
|
ciao,
hai provato a dare un'occhiata qui? http://www.advancedlinuxprogramming.com/downloads.html scaricati il libro, forse è un settaggio errato dei semafori...
__________________
Ciao ciao cagnolino Billy ![]() ![]() ![]() MacMini late 2009, 2.53GHz, 4GB ram, 320GB hard disk, Snow Leopard 10.8.2 - iPod Nano 6th gen. XBOX Live GamerTag: InsaneMau |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Purtroppo quel libro cita EINTR una sola volta, e semop() ha una trattazione più ridotta della manpage...
Cmq guardando quelle poche sources che ci sono in giro, ho visto che molti mettono semop() dentro un while, che si ripete finchè l'errore è EINTR. Che senso ha questo "riprovare all'infinito"? Also, se non uso gdb le chiamate di threading si comportano in maniera del tutto differente. I love Linux ![]() |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
EINTR viene ritornato quando viene lanciato un segnale durante la chiamata di sistema.
La man page di semop lo conferma. Che segnali tratti ? Gdb fa dei smanettamenti con i signal handler per poter gestire l'interruzione del processo debuggato, i comportamenti "diversi" potrebbero essere dovuti a quello; con che chiamate ti succede ? Quali sono i comportamenti inaspettati ?
__________________
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: Dec 2005
Città: Istanbul
Messaggi: 1817
|
La chiamata è ritornata perchè interrotta da un segnale. Di per sè non ha fatto niente di male per cui, se fai uso o gestisci segnali, ha senso continuare a riprovare (se la chiamata è bloccante perlomeno).
__________________
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 |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Sembrerebbe che il problema cmq è gbd, perchè se lo faccio girare normalmente va alla perfezione... cioè crasha poco dopo per motivi che senza gdb non posso individuare
![]() Mi sa che la versione unix la faccio su OSX ![]() |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Dubito che con OSX ti andra' meglio, perche' comunque gdb dovra' installare di signal handler e questi ti faranno fallire la chiamata in attesa.
Prova piuttosto ad usare funzionalita' di tracing (lttng ad esempio) oppure valgrind
__________________
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
|
Codice:
struct sembuf oper; int err; DEBUG_ASSERT( SID > 0 ); oper.sem_num = 0; oper.sem_op = op; oper.sem_flg = 0; do err = semop( SID, &oper, 1 ); //keep repeating on interruptions while( errno == EINTR ); return NOERROR( err ); A presto per la prossima puntata ![]() |
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Uppo il thread perchè in realtà, solo la Wait funzionava, quindi con op = -1.
Se op = 1 o comunque n > 0, il do while diventa un ciclo infinito, cioè semop da sempre errore EINTR. Mistero! |
![]() |
![]() |
![]() |
#11 | |||
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
Quote:
La tua chiamata molto probabilmente non fallisce affatto, solo che il valore di errno è indefinito e incidentalmente ha il valore che era stato precedentemente impostato da un'altra chiamata. Tieni presente anche che Quote:
Comunque, qualcosa come il seguente dovrebbe andare meglio (non testato): Codice:
do err = semop( SID, &oper, 1 ); //keep repeating on interruptions while( err && errno == EINTR );
__________________
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: 23:17.