Domanda

La denominazione di questa funzione sembra che questo è un certo roba complicata in corso. Quando esattamente si fa a sapere che questa è la strada da percorrere invece di fare qualcosa di simile:

Preparazione     CRITICAL_SECTION cs;     int * p = malloc (sizeof (int)); // Assegnazione del sito     InitializeCriticalSection (& cs); // SUGGERIMENTO per la prima scrittura

Thread # 1      {     * P = 1; // Scrivi     }

Thread # 2      {     EnterCriticalSection (& cs);     * P = 2; // seconda operazione di scrittura     LeaveCriticalSection (& cs);     }

Ho una scrittura che viene fatto in un thread:

Run()
{
// some code
m_bIsTerminated = TRUE;
// some more code
}

Poi, ho una lettura che viene fatto in un altro thread (potenzialmente allo stesso tempo):

Terminate()
{
// some code
if( m_bIsTerminated )
{
m_dwThreadId = 0;
m_hThread = NULL;
m_evExit.SetEvent();
return;
}
// even more code
}

Qual è la soluzione migliore per risolvere questa condizione di gara? Sono sezioni critiche la strada da percorrere o è l'uso di InterlockedExchangeAdd () più utile?

È stato utile?

Soluzione

InterlockedExchangeAdd viene utilizzata per aggiungere un valore ad un intero come un'operazione atomica, il che significa che non sarà necessario utilizzare una sezione critica. Questo elimina anche il rischio di una situazione di stallo, se uno dei tuoi thread genera un'eccezione -. È necessario fare in modo che non si tiene alcun blocco di qualsiasi tipo come che impedirebbe altri thread di acquisire che il blocco

Per lo scenario si può sicuramente utilizzare una funzione Interlocked ...-, ma vorrei utilizzare un evento (CreateEvent, SetEvent, WaitForSingleObject), probabilmente perché mi ritrovo spesso a dover attendere per più di un oggetto (si può aspettare per zero secondi nello scenario).

UPD: Utilizzando volatile per la variabile può funzionare, tuttavia non è consigliabile, vedi: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html e http://www-949.ibm. com / software / razionale / caffè / blog / CCPP-parallelo-multicore / tag / c% 2B% 2B0x per esempio.

Se si vuole essere portatile, un'occhiata a boost :: filo .

Altri suggerimenti

Nel tuo caso, non c'è alcuna condizione di competizione. La variabile non viene mai azzerato di nuovo a FALSE, è vero? E 'solo un interruttore "si prega di morire" per il filo, giusto? Quindi non c'è bisogno per la sincronizzazione di qualsiasi tipo.

La famiglia InterlockedXXX di funzioni fa uso di atomiche comandi a 3 operandi di Intel CPU (xadd e CMPXCNG). Quindi sono molto meno costosa di una sezione critica. E quello che si desidera per l'assegnazione thread-safe è InterlockedCompareExchange ().

UPD:. E il marchio la variabile come volatile

Assicurarsi m_bIsTerminated è contrassegnato come volatile, e si dovrebbe essere ok. Anche se sembra piuttosto strano per me che avresti // altro codice dopo aver impostato "è terminato" true. Che cosa fa esattamente quella variabile indica?

Il tuo "race condition" è che i vari elementi del // più codice in grado di eseguire in ordine diverso. La variabile non aiuta che. È il vostro obiettivo per ottenere loro di eseguire in un ordine deterministico? Se sì, avresti bisogno di un variabile di condizione di aspettare un thread e impostare in un altro. Se proprio non si vuole che l'esecuzione contemporaneamente, una sezione critica andrebbe bene.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top