Condividi tramite


Confronto delle strutture di dati di sincronizzazione con l'API Windows

In questo argomento viene confrontato il comportamento delle strutture di dati di sincronizzazione fornite dal runtime di concorrenza a quelle fornite dall'API Di Windows.

Le strutture dei dati di sincronizzazione fornite dal runtime di concorrenza seguono il modello di threading cooperativo. Nel modello di threading cooperativo, le primitive di sincronizzazione producono in modo esplicito le risorse di elaborazione ad altri thread. Questo comportamento è diverso dal modello di threading preemptive, in cui le risorse di elaborazione vengono trasferite ad altri thread dall'utilità di pianificazione di controllo o dal sistema operativo.

critical_section

La classe concurrency::critical_section è simile alla struttura di Windows CRITICAL_SECTION perché può essere usata solo dai thread di un processo. Per altre informazioni sulle sezioni critiche nell'API Windows, vedere Oggetti sezione critica.

reader_writer_lock

La classe concurrency::reader_writer_lock è simile ai blocchi snelli di lettura/scrittura (SRW) di Windows. La tabella seguente illustra le analogie e le differenze.

Funzionalità Classe reader_writer_lock Blocco SRW
Non reentrant
Può alzare di livello un lettore a un writer (supporto per l'aggiornamento) No No
Può abbassare di livello un writer a un lettore (supporto per il downgrade) No No
Blocco delle preferenze di scrittura No
Accesso FIFO ai writer No

Per altre informazioni sui blocchi SRW, vedere Blocchi SRW (Slim Reader/Writer) in Platform SDK.

evento

La classe di evento concurrency::event è simile a un evento di reimpostazione manuale di Windows senza nome. Tuttavia, un event oggetto si comporta in modo cooperativo, mentre un evento di Windows si comporta in modo preemptive. Per altre informazioni sugli eventi di Windows, vedere Oggetti evento.

Esempio

Descrizione

Per comprendere meglio la differenza tra la event classe e gli eventi di Windows, prendere in considerazione l'esempio seguente. Questo esempio consente all'utilità di pianificazione di creare al massimo due attività simultanee e quindi chiama due funzioni simili che usano la event classe e un evento di reimpostazione manuale di Windows. Ogni funzione crea prima di tutto diverse attività che attendono che un evento condiviso venga segnalato. Ogni funzione restituisce quindi le attività in esecuzione e quindi segnala l'evento. Ogni funzione attende quindi l'evento segnalato.

Codice

// event-comparison.cpp
// compile with: /EHsc
#include <windows.h>
#include <concrtrm.h>
#include <ppl.h>
#include <iostream>
#include <sstream>

using namespace concurrency;
using namespace std;

// Demonstrates the usage of cooperative events.
void RunCooperativeEvents()
{
   // An event object.
   event e;

   // Create a task group and execute five tasks that wait for
   // the event to be set.
   task_group tasks;
   for (int i = 0; i < 5; ++i)
   {
      tasks.run([&] {
         // Print a message before waiting on the event.
         wstringstream ss;
         ss << L"\t\tContext " << GetExecutionContextId() 
            << L": waiting on an event." << endl; 
         wcout << ss.str();

         // Wait for the event to be set.
         e.wait();

         // Print a message after the event is set.
         ss = wstringstream();
         ss << L"\t\tContext " << GetExecutionContextId() 
            << L": received the event." << endl; 
         wcout << ss.str();
      });
   }

   // Wait a sufficient amount of time for all tasks to enter 
   // the waiting state.
   Sleep(1000L);

   // Set the event.

   wstringstream ss;
   ss << L"\tSetting the event." << endl; 
   wcout << ss.str();

   e.set();

   // Wait for all tasks to complete.
   tasks.wait();
}

// Demonstrates the usage of preemptive events.
void RunWindowsEvents()
{
   // A Windows event object.
   HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("Windows Event"));

   // Create a task group and execute five tasks that wait for
   // the event to be set.
   task_group tasks;
   for (int i = 0; i < 5; ++i)
   {
      tasks.run([&] {
         // Print a message before waiting on the event.
         wstringstream ss;
         ss << L"\t\tContext " << GetExecutionContextId() 
            << L": waiting on an event." << endl; 
         wcout << ss.str();

         // Wait for the event to be set.
         WaitForSingleObject(hEvent, INFINITE);

         // Print a message after the event is set.
         ss = wstringstream();
         ss << L"\t\tContext " << GetExecutionContextId() 
            << L": received the event." << endl; 
         wcout << ss.str();
      });
   }

   // Wait a sufficient amount of time for all tasks to enter 
   // the waiting state.
   Sleep(1000L);

   // Set the event.

   wstringstream ss;
   ss << L"\tSetting the event." << endl; 
   wcout << ss.str();

   SetEvent(hEvent);

   // Wait for all tasks to complete.
   tasks.wait();

   // Close the event handle.
   CloseHandle(hEvent);
}

int wmain()
{
   // Create a scheduler policy that allows up to two 
   // simultaneous tasks.
   SchedulerPolicy policy(1, MaxConcurrency, 2);

   // Attach the policy to the current scheduler.
   CurrentScheduler::Create(policy);
   
   wcout << L"Cooperative event:" << endl;
   RunCooperativeEvents();

   wcout << L"Windows event:" << endl;
   RunWindowsEvents();
}

Commenti

Questo esempio produce l'output di esempio seguente:

Cooperative event:
    Context 0: waiting on an event.
    Context 1: waiting on an event.
    Context 2: waiting on an event.
    Context 3: waiting on an event.
    Context 4: waiting on an event.
    Setting the event.
    Context 5: received the event.
    Context 6: received the event.
    Context 7: received the event.
    Context 8: received the event.
    Context 9: received the event.
Windows event:
    Context 10: waiting on an event.
    Context 11: waiting on an event.
    Setting the event.
    Context 12: received the event.
    Context 14: waiting on an event.
    Context 15: received the event.
    Context 16: waiting on an event.
    Context 17: received the event.
    Context 18: waiting on an event.
    Context 19: received the event.
    Context 13: received the event.

Poiché la event classe si comporta in modo cooperativo, l'utilità di pianificazione può riallocare le risorse di elaborazione in un altro contesto quando un evento è in attesa di entrare nello stato segnalato. Pertanto, più lavoro viene eseguito dalla versione che usa la event classe . Nella versione che usa eventi di Windows, ogni attività in attesa deve entrare nello stato segnalato prima dell'avvio dell'attività successiva.

Per altre informazioni sulle attività, vedere Parallelismo delle attività.

Vedi anche

Strutture di dati di sincronizzazione