GNU/Linux >> Belajar Linux >  >> Linux

Apa yang setara dengan C++ untuk AutoResetEvent di Linux?

Variabel bersyarat adalah TIDAK setara dengan AutoResetEvent. Mereka setara dengan Monitor. Perbedaannya sangat penting dan dapat menyebabkan kebuntuan jika tidak digunakan dengan benar:

Bayangkan dua utas A dan B dalam program C#. A memanggil WaitOne() dan B memanggil Set(). Jika B mengeksekusi Set() sebelum A mencapai panggilan ke WaitOne(), tidak ada masalah karena sinyal yang dikirim ke AutoResetEvent() oleh Set() tetap ada dan akan tetap disetel hingga WaitOne() dijalankan.

Sekarang di C, bayangkan dua utas C dan D. C memanggil wait(), D memanggil notify(). Jika C sudah menunggu ketika D memanggil notify() semuanya baik-baik saja. Jika C tidak berhasil mencapai wait() sebelum D memanggil notify(), Anda mengalami kebuntuan karena sinyal hilang jika tidak ada yang menunggu dan status variabel kondisional masih "tidak disetel".

Berhati-hatilah dengan hal ini.


Saya cukup yakin Anda sedang mencari variabel kondisi. Jawaban yang diterima untuk pertanyaan SO lainnya ini:Variabel kondisi dalam C# -- sepertinya mengonfirmasinya.

Lihat mis. tutorial ini untuk detail tentang variabel kondisi di utas POSIX.


AutoResetEvent paling mirip dengan semaphore biner. Orang yang mengatakan "variabel kondisional" tidak salah, tetapi variabel kondisi digunakan dalam situasi yang serupa, alih-alih menjadi objek yang serupa. Anda dapat menerapkan AutoResetEvent (tanpa nama) di atas variabel kondisi:

#include <pthread.h>
#include <stdio.h>

class AutoResetEvent
{
  public:
  explicit AutoResetEvent(bool initial = false);

  ~AutoResetEvent();
  void Set();
  void Reset();

  bool WaitOne();

  private:
  AutoResetEvent(const AutoResetEvent&);
  AutoResetEvent& operator=(const AutoResetEvent&); // non-copyable
  bool flag_;
  pthread_mutex_t protect_;
  pthread_cond_t signal_;
};

AutoResetEvent::AutoResetEvent(bool initial)
: flag_(initial)
{
  pthread_mutex_init(&protect_, NULL);
  pthread_cond_init(&signal_, NULL);
}

void AutoResetEvent::Set()
{
  pthread_mutex_lock(&protect_);
  flag_ = true;
  pthread_mutex_unlock(&protect_);
  pthread_cond_signal(&signal_);
}

void AutoResetEvent::Reset()
{
  pthread_mutex_lock(&protect_);
  flag_ = false;
  pthread_mutex_unlock(&protect_);
}

bool AutoResetEvent::WaitOne()
{
  pthread_mutex_lock(&protect_);
  while( !flag_ ) // prevent spurious wakeups from doing harm
    pthread_cond_wait(&signal_, &protect_);
  flag_ = false; // waiting resets the flag
  pthread_mutex_unlock(&protect_);
  return true;
}

AutoResetEvent::~AutoResetEvent()
{
  pthread_mutex_destroy(&protect_);
  pthread_cond_destroy(&signal_);
}


AutoResetEvent event;

void *otherthread(void *)
{
  event.WaitOne();
  printf("Hello from other thread!\n");
  return NULL;
}


int main()
{
  pthread_t h;
  pthread_create(&h, NULL, &otherthread, NULL);
  printf("Hello from the first thread\n");
  event.Set();

  pthread_join(h, NULL);
  return 0;
}

Namun, jika Anda memerlukan acara setel ulang otomatis bernama, Anda mungkin ingin melihat semaphore, dan mungkin sedikit lebih sulit menerjemahkan kode Anda. Bagaimanapun saya akan melihat dokumentasi untuk pthreads di platform Anda dengan hati-hati, variabel kondisi dan kejadian reset otomatis tidak sama dan tidak berperilaku sama.


Linux
  1. Apa tujuan dari file .bash_profile di bawah Direktori Beranda Pengguna Di Linux?

  2. Apa persamaan Linux dengan jeda DOS?

  3. Apa yang setara dengan getch() &getche() di Linux?

  1. Apa yang setara dengan Unix/Linux dari I/O Terdaftar?

  2. Apa lokasi pemasangan konvensional untuk aplikasi di Linux?

  3. Apa yang setara dengan ~ (tilde) Linux di Windows?

  1. Apa yang setara dengan perintah Linux sudo fdisk -l di MacOS?

  2. Apa yang setara dengan Active Directory di Linux

  3. Apa yang setara dengan Linux dari Windows Startup?