GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Was ist das C++-Äquivalent für AutoResetEvent unter Linux?

Bedingte Variablen sind NICHT das Äquivalent von AutoResetEvent. Sie sind das Äquivalent von Monitoren. Der Unterschied ist kritisch und kann bei unsachgemäßer Verwendung zu Deadlocks führen:

Stellen Sie sich zwei Threads A und B in einem C#-Programm vor. A ruft WaitOne() auf und B ruft Set() auf. Wenn B Set() ausführt, bevor A den Aufruf von WaitOne() erreicht, gibt es kein Problem, da das von Set() an AutoResetEvent() gesendete Signal dauerhaft ist und gesetzt bleibt, bis ein WaitOne() ausgeführt wird.

Stellen Sie sich nun in C zwei Threads C und D vor. C ruft wait() auf, D ruft notification() auf. Wenn C bereits wartet, wenn D notification() aufruft, ist alles in Ordnung. Wenn C es nicht geschafft hat, wait() zu erreichen, bevor D notification() aufruft, haben Sie einen Deadlock, weil das Signal verloren geht, wenn niemand darauf wartet und der Status der bedingten Variablen immer noch "ungesetzt" ist.

Seien Sie diesbezüglich sehr vorsichtig.


Ich bin mir ziemlich sicher, dass Sie nach Bedingungsvariablen suchen. Die akzeptierte Antwort auf diese andere SO-Frage:Bedingungsvariablen in C# – scheint dies zu bestätigen.

Siehe z.B. dieses Tutorial für Details zu Bedingungsvariablen in POSIX-Threads.


Ein AutoResetEvent ähnelt am ehesten einem binären Semaphor. Leute, die "bedingte Variablen" sagen, sind per se nicht falsch, aber Bedingungsvariablen werden in ähnlichen Situationen verwendet, anstatt ähnliche Objekte zu sein. Sie können ein (unbenanntes) AutoResetEvent zusätzlich zu Bedingungsvariablen implementieren:

#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;
}

Wenn Sie jedoch benannte Auto-Reset-Ereignisse benötigen, sollten Sie sich wahrscheinlich Semaphoren ansehen und haben möglicherweise etwas schwierigere Zeiten beim Übersetzen Ihres Codes. In jedem Fall würde ich mir die Dokumentation für pthreads auf Ihrer Plattform genau ansehen, Bedingungsvariablen und Auto-Reset-Ereignisse sind nicht gleich und verhalten sich nicht gleich.


Linux
  1. Was ist das Linux-Äquivalent zur DOS-Pause?

  2. Was ist das Äquivalent zu getch() &getche() in Linux?

  3. Was ist das Unix/Linux-Äquivalent von Registered I/O?

  4. Installieren von Bibliotheken und Header-Dateien unter Ubuntu Linux für die C/C++-Entwicklung

  5. Was ist das Äquivalent von Linux's updatedb-Befehl für den Mac?

Linux vs. Unix:Was ist der Unterschied?

Was ist die beste Linux-Distribution für Anfänger?

Was ist die Shell unter Linux?

Was ist der Kill-Befehl in Linux?

Was entspricht dem Linux-Befehl sudo fdisk -l in MacOS?

Was ist das Linux-Äquivalent zum Windows-Startup?