Bagikan melalui


Membandingkan Struktur Data Sinkronisasi dengan WINDOWS API

Topik ini membandingkan perilaku struktur data sinkronisasi yang disediakan oleh Concurrency Runtime dengan yang disediakan oleh Windows API.

Struktur data sinkronisasi yang disediakan oleh Concurrency Runtime mengikuti model threading kooperatif. Dalam model utas kooperatif, primitif sinkronisasi secara eksplisit menghasilkan sumber daya pemrosesan mereka ke utas lain. Ini berbeda dari model utas preemptive, di mana sumber daya pemrosesan ditransfer ke utas lain oleh penjadwal pengontrol atau sistem operasi.

critical_section

Kelas konkurensi::critical_section menyerupai struktur Windows CRITICAL_SECTION karena hanya dapat digunakan oleh utas satu proses. Untuk informasi selengkapnya tentang bagian penting di Windows API, lihat Objek Bagian Penting.

reader_writer_lock

Kelas konkurensi::reader_writer_lock menyerupan kunci windows slim reader/writer (SRW). Tabel berikut menjelaskan persamaan dan perbedaan.

Fitur reader_writer_lock kelas Kunci SRW
Non-reentrant Ya Ya
Dapat mempromosikan pembaca ke penulis (dukungan peningkatan) Tidak Tidak
Dapat menurunkan penulis ke pembaca (menurunkan dukungan) Tidak Tidak
Kunci preferensi tulis Ya Tidak
Akses FIFO ke penulis Ya Tidak

Untuk informasi selengkapnya tentang kunci SRW, lihat Kunci Slim Reader/Writer (SRW) di Platform SDK.

event

Kelas konkurensi::event menyerupan peristiwa reset manual Windows yang tidak disebutkan namanya. Namun, objek event berperilaku kooperatif, sedangkan peristiwa Windows berperilaku lebih awal. Untuk informasi selengkapnya tentang peristiwa Windows, lihat Objek Peristiwa.

Contoh

Deskripsi

Untuk lebih memahami perbedaan antara event kelas dan peristiwa Windows, pertimbangkan contoh berikut. Contoh ini memungkinkan penjadwal untuk membuat paling banyak dua tugas simultan dan kemudian memanggil dua fungsi serupa yang menggunakan event kelas dan peristiwa reset manual Windows. Setiap fungsi terlebih dahulu membuat beberapa tugas yang menunggu peristiwa bersama menjadi sinyal. Setiap fungsi kemudian menghasilkan tugas yang sedang berjalan dan kemudian memberi sinyal peristiwa. Setiap fungsi kemudian menunggu peristiwa yang disinyalir.

Kode

// 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();
}

Komentar

Contoh ini menghasilkan contoh output berikut:

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.

event Karena kelas berperilaku kooperatif, penjadwal dapat merealokasi sumber daya pemrosesan ke konteks lain ketika suatu peristiwa menunggu untuk memasuki status yang disinyalir. Oleh karena itu, lebih banyak pekerjaan dicapai oleh versi yang menggunakan event kelas . Dalam versi yang menggunakan peristiwa Windows, setiap tugas tunggu harus memasukkan status yang disinyalir sebelum tugas berikutnya dimulai.

Untuk informasi selengkapnya tentang tugas, lihat Paralelisme Tugas.

Lihat juga

Struktur Data Sinkronisasi