GNU/Linux >> Znalost Linux >  >> Linux

Jaký je ekvivalent C++ pro AutoResetEvent pod Linuxem?

Podmíněné proměnné NE ekvivalent AutoResetEvent. Jsou ekvivalentem monitorů. Rozdíl je kritický a může způsobit uváznutí, pokud není používán správně:

Představte si dvě vlákna A a B v programu C#. A volá WaitOne() a B volá Set(). Pokud B provede Set() předtím, než A dosáhne volání WaitOne(), nenastane žádný problém, protože signál odeslaný do AutoResetEvent() pomocí Set() je trvalý a zůstane nastavený, dokud nebude provedena WaitOne().

Nyní v C si představte dvě vlákna C a D. C volá wait(), D volá notify(). Pokud C již čeká, když D volá notify(), je vše v pořádku. Pokud se C nepodařilo dosáhnout wait() předtím, než D zavolá notify(), došlo k uváznutí, protože signál se ztratí, pokud na něj nikdo nečeká a stav podmíněné proměnné je stále "unset".

Buďte na to velmi opatrní.


Jsem si docela jistý, že hledáte proměnné podmínek. Zdá se, že přijatá odpověď na tuto další otázku SO:Podmínkové proměnné v C# to potvrzuje.

Viz např. tento tutoriál obsahuje podrobnosti o proměnných podmínek ve vláknech POSIX.


AutoResetEvent se nejvíce podobá binárnímu semaforu. Lidé, kteří říkají "podmíněné proměnné" nejsou samy o sobě špatné, ale podmíněné proměnné se používají v podobných situacích, spíše než jako podobné objekty. Nad proměnnými podmínky můžete implementovat (nepojmenovaný) AutoResetEvent:

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

Pokud však potřebujete pojmenované události automatického resetování, pravděpodobně se budete chtít podívat na semafory a překlad kódu může být trochu obtížnější. V každém případě bych se pečlivě podíval na dokumentaci k pthreadům na vaší platformě, proměnné podmínek a události automatického resetu nejsou stejné a nechovají se stejně.


Linux
  1. Linux vs. Unix:Jaký je rozdíl?

  2. Jaký je účel souboru .bash_profile pod uživatelským domovským adresářem v Linuxu

  3. Co je linuxový ekvivalent pozastavení DOSu?

  1. Jaký je ekvivalent getch() &getche() v Linuxu?

  2. Jaký by byl ekvivalent Win32 API v linuxu?

  3. Co je Unix/Linux ekvivalentem Registered I/O?

  1. Instalace knihoven a hlavičkových souborů pod Ubuntu Linux pro vývoj C/C++

  2. Jaký je ekvivalent linuxového příkazu updatedb pro Mac?

  3. Co je ekvivalentní příkazu Linux File pro Windows?