|
|||||||
|
|
|
![]() |
|
|
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 20: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: 05:37.




















