Sto cercando qualcosa per cui poter usare votazione (piace select
, kqueue
, epoll
io no polling impegnato) in C / C ++. In altre parole, devo bloccare un thread e quindi svegliarlo in un altro thread con il minor sovraccarico possibile.
UN mutex
+ condition variable
funziona, ma ci sono molte spese generali. UN futex
funziona anche, ma questo è solo per Linux (o forse no?). Non è richiesta una sincronizzazione aggiuntiva finché votazione funziona correttamente, ad es. nessuna gara quando chiamo wait
e wake
in due fili.
Modifica: Se una tale "struttura" non esiste in FreeBSD, come crearne una con tipi incorporati in C ++ 11 e chiamate di sistema?
Edit2: Dato che questa domanda viene migrata su SO, mi piacerebbe renderla più generale (non solo per FreeBSD)
risposte:
3 per risposta № 1i semafori non sono mutex e funzionerebbero con un po 'meno di sovraccarico (evitando ad esempio il re-lock di mutex + condvar)
Si noti che poiché qualsiasi soluzione in cui un thread è in attesa fino a quando non viene svegliata implica un kernel syscall, non lo è ancora a buon mercato. Supponendo che x86_64 glibc e FreeBSD libc siano entrambe implementazioni ragionevoli, il costo inevitabile sembra essere:
- sincronizzazione in modalità utente del conteggio (con un CAS o simile)
- gestione del kernel della coda di attesa e thread sleep / wait
Suppongo che l'overhead di mutex + condvar di cui sei preoccupato sia la sequenza cond_wait-> re-lock-> unlock, che in effetti è evitata qui.
2 per risposta № 2
Volete semafori e non mutex per la segnalazione tra i thread to.
http://man7.org/linux/man-pages/man3/sem_wait.3.html
I semafori possono essere usati come un contatore come sehai una coda, incrementi (invii) al semaforo ogni volta che inserisci un messaggio e il tuo ricevitore diminuisce (attendi) sul semaforo per ogni messaggio che estrae. Se il contatore raggiunge lo zero, il ricevitore si bloccherà fino a quando non viene pubblicato qualcosa.
Quindi uno schema tipico è quello di combinare un mutex e un semaforo come;
sender:
mutex.lock
insert message in shared queue
mutex.unlock
semaphore.post
receiver:
semaphore.wait
mutex.lock
dequeue message from shared structure
mutex.unlock