/ / Esistono equivalenti al futex in Linux / Unix? - c ++, c, multithreading

Ci sono degli equivalenti al futex in Linux / Unix? - c ++, c, multithreading

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 № 1

i 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:

  1. sincronizzazione in modalità utente del conteggio (con un CAS o simile)
  2. 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