2015-09-24 8 views
8

Nel corso del commento allo a recent question, è sorta una domanda sussidiaria su a che punto si può prevedere che venga eseguita una richiesta di cancellazione per un thread di pthreads con annullabilità PTHREAD_CANCEL_DEFERRED. Riferimenti a the standard e un po 'di giurisprudenza seguì. Non sono molto preoccupato in particolare se mi sono sbagliato nei miei commenti su quella domanda, ma io vorrei essere sicuro di capire correttamente le disposizioni di POSIX.Che cosa significa POSIX che un thread è "sospeso"?

La sezione più pertinente della norma dice

Quando un thread è cancelability abilitato e una richiesta di cancellazione è stato fornito con quel filo come destinazione, e il filo chiede allora qualsiasi funzione che è un punto di cancellazione [...], la richiesta di cancellazione deve essere applicata prima che la funzione ritorni. Se una discussione ha annullabilità abilitata e una richiesta di cancellazione viene effettuata con il thread come destinazione mentre la discussione è sospesa in un punto di annullamento, il thread deve essere risvegliato e la richiesta di cancellazione deve essere presa in considerazione.

Cosa significa, tuttavia, che un thread sia "sospeso"? POSIX definisce esplicitamente il termine per i processi, ma non, per quanto posso determinare, per i thread. D'altra parte, POSIX documenta la sospensione del thread tra i comportamenti di una manciata di funzioni, incluse, ma non limitate a, alcune di quelle relative agli oggetti di sincronizzazione. Si dovrebbe quindi concludere che quelli servono collettivamente come la definizione pertinente del termine?

E come tutto questo riguarda la questione che ha generato questa linea di indagine, dato che POSIX non specifica sospensione filo come parte del comportamento di read(), fread(), o uno qualsiasi dei file generale o lo streaming di funzioni di I/O, se un thread non sta facendo progressi per essere bloccato su I/O, significa necessariamente che è "sospeso" ai fini della cancellazione?

+2

Lo standard IEEE 1003.1 (POSIX) afferma esplicitamente che è allineato con lo standard ISO/IEC 9899 (C). Lo standard C cita [ISO/IEC 2382 (Vocabolario della tecnologia dell'informazione)] (https://www.iso.org/obp/ui/#iso:std:iso-iec:2382:ed-1:v1:en) per il suo gergo. Sfortunatamente, nemmeno ISO/IEC 2382 definisce _suspended_, e persino usa quella parola in alcune delle definizioni. Quello che ne deduco è che "sospeso" è considerato una parola chiave inglese, adatta per l'uso nelle spiegazioni. La mia interpretazione personale di sospeso è "lo stato di un thread che non utilizza attualmente il tempo del processore". –

+0

@IwillnotexistIdonotexist, l'allineamento con C è un'osservazione utile, grazie. Trovo che "attualmente non usi il tempo del processore" sia un'interpretazione preoccupante, perché sembra che copra i thread che * potrebbe * essere in esecuzione, ma che sono stati anticipati. Ciò non sembra corrispondere: ogni indicazione è che la sospensione del thread è uno stato in cui un thread * viene * impedito * in esecuzione anche se la CPU sarebbe altrimenti disponibile per esso. Può darsi che gli standard C e POSIX presuppongano l'applicazione di un'interpretazione naturale, ma i dettagli sono importanti e non sono chiari (per me). –

+1

Mi sembra naturale pensare che i thread eseguibili che non sono in esecuzione siano sospesi, per mancanza di una parola migliore.Su un processore 'n'-core molto carico, potrebbero esserci'> n' _runnable_ processes, ma al massimo 'n' di questi possono essere creati _running_; Tutti gli altri devono essere _not-running_, o come POSIX _might_ averlo, "la loro esecuzione è sospesa" in attesa del loro turno. Cosa ne pensi? Un thread eseguibile attende che il quantum del tempo di un thread in esecuzione scada sospeso? Che ne dite di un thread in esecuzione il cui quantum scade e, anche se ancora eseguibile, viene disattivato? Che dire dei thread interrotti? –

risposta

1

read, fread e friends sono chiamate di sistema e come tali eseguiranno un commutatore di contesto ed eseguiranno dal contesto del kernel fino a quando tali funzioni non saranno completate. L'interruzione di un contesto del kernel non rientra nell'ambito di pthreads, pertanto non causerà una cancellazione.

Non ho un riferimento per questo, ma per quanto ne so, la sospensione del thread nel contesto dei thread Posix ha a che fare con gli oggetti di sincronizzazione (come i futex).

+1

Grazie, ma sto cercando argomenti basati su * documentazione *, non basati su particolari * implementazioni *. –

+0

Uh, quelli syscall * sono * interrompibili. 'man read: [...] Non è un errore se questo numero è inferiore al numero di byte richiesti; questo può accadere ad esempio [...] perché read() è stato interrotto da un segnale. [...] EINTR La chiamata è stata interrotta da un segnale prima della lettura di qualsiasi dato; vedere il segnale (7) .' – EOF

2

Definizione della sospensione nel contesto di fili:

3.107 Condizione variabile

Un oggetto di sincronizzazione che consente un thread di sospendere l'esecuzione, più volte, fino a qualche predicato associato diventa vero. Un thread la cui esecuzione è sospesa su una variabile di condizione si dice che sia bloccato sulla variabile condition.

Da: http://pubs.opengroup.org/onlinepubs/9699919799/

Questa non è una risposta diretta, solo una definizione - troppo grande per un commento. Bloccato == sospeso.

+1

Sì, l'ho visto. Lo considero come la definizione del comportamento di 'pthread_cond_wait()' per includere la sospensione del thread. Altre funzioni ('wait()', 'sleep()', ...) sono anche documentate per causare la sospensione del thread, tuttavia, in modo che non possa essere una definizione completa. –

+0

"L'oggetto di sincronizzazione" non è necessariamente locale al codice, potrebbe invece essere un oggetto implementato dal kernel. Quello che dobbiamo trovare è la discussione (l'intento) dietro lo sviluppo della definizione per essere sicuri. Qualche aiuto lì? –

+0

Da un po 'di tempo sto studiando aspetti di POSIX e spegnimento, ma temo di non avere un'idea particolare del suo sviluppo. In questo caso, vedo buone ragioni dal punto di vista dello sviluppatore per volere che "sospeso" sia definito in modo inclusivo, ma buone ragioni dalle prospettive degli scrittori standard e degli implementatori di volere che sia definito in modo restrittivo. –

3

Un thread sospeso è uno che, come dici tu, è bloccato su una presa di lettura, in attesa che un semaforo sia disponibile, ecc.

Dato che le implementazioni POSIX variano ai bordi ingannevoli e che esiste la possibilità che un thread sia bloccato in una funzione che non è un punto di annullamento, potrebbe essere che fare affidamento sull'annullamento nel codice che deve essere portato potrebbe essere più difficile di quello che vale.

Non l'ho mai usato, ho sempre scelto di avere il codice per istruire esplicitamente un thread da terminare (normalmente un messaggio lungo una pipe o una coda). Questo è molto semplice con un sistema di processi sequenziali comunicanti o modello di attore.

In questo modo la pulizia può essere eseguita sotto il proprio controllo, liberando memoria, ecc. Secondo necessità. Non ho idea se un thread cancellato pulirà la sua memoria (non sospetto), o se ci sia l'opzione per una cosa di tipo at_exit() (ci potrebbe essere). Nel complesso, penso che il comportamento dell'applicazione sia controllato più accuratamente se esiste un solo modo in cui un thread può uscire.

== == EDIT

@JohnBollinger,

La lingua utilizzata If a thread has cancelability enabled and a cancellation request is made with the thread as a target while the thread is suspended at a cancellation point potrebbe essere interpretato nel modo IF a thread has cancelability enabled AND IF cancelled and IF implementation suspends blocked threads AND IF the thread is blocked THEN the thread shall be awakened.... In altre parole, la stanno lasciando all'implicatore del sottosistema POSIX.

L'implementazione di select() da parte di Cygwin non ha (o almeno non ha comportato) la sospensione del thread. Invece genera un thread di polling per descrittore di file per testare l'attività segnalabile, a causa della fondamentale mancanza di qualcosa di simile a select() in Windows (si avvicina, ma non sigaro.) Win32 select() funziona solo su socket). Anche le implementazioni di select() negli anni '80 hanno funzionato in questo modo.

Potrebbe essere per motivi come questo che POSIX è riluttante a definire chiaramente quando un thread è sospeso. Storicamente molte implementazioni di select() erano così, rendendo un campo minato per un comitato standard per dire quando un thread potrebbe o non potrebbe essere sospeso. Ovviamente le complessità causate da select() si applicherebbero anche a un processo ma poiché POSIX definisce un processo sospeso sembra strano che non possano/non abbiano esteso la definizione ai thread.

Potrebbe essere il modo in cui vengono implementati i thread; è possibile avere un'implementazione POSIX che non utilizza thread OS (un po 'come le prime implementazioni di ADA nei giorni in cui i sistemi operativi non eseguivano affatto i thread), e in tale implementazione un thread bloccato potrebbe non essere sospeso (nel senso di non prendere alcun ciclo della CPU).

+2

"Un thread sospeso è uno che, come dici tu, è bloccato su un socket letto, in attesa che un semaforo sia disponibile, ecc.".In realtà no, io * non * dico questo. In particolare, sono dubbioso che POSIX definisca un thread bloccato su una read da sospendere. Sarei lieto di sentire le tue basi per un tale reclamo - questo è il genere di cose che sto cercando. –

+0

La pulizia dell'annullamento del thread può essere eseguita da (sorpresa!) 'Pthread_cleanup_push()/pthread_cleanup_pop()'. – EOF

+0

@JohnBollinger, è abbastanza giusto. Non ho detto che POSIX lo definisce in questo modo, ma ovviamente è normale che le implementazioni sospendano un thread bloccato. Ho aggiunto alla mia risposta – bazza