GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cuál es el equivalente de C++ para AutoResetEvent en Linux?

Las variables condicionales son NO el equivalente de AutoResetEvent. Son el equivalente a los Monitores. La diferencia es crítica y puede causar interbloqueos si no se usa correctamente:

Imagine dos subprocesos A y B en un programa C#. A llama a WaitOne() y B llama a Set(). Si B ejecuta Set() antes de que A alcance la llamada a WaitOne(), no hay problema porque la señal enviada a AutoResetEvent() por Set() es persistente y permanecerá establecida hasta que se ejecute WaitOne().

Ahora en C, imagina dos subprocesos C y D. C llama a esperar (), D llama a notificar (). Si C ya está esperando cuando D llama a notificar () todo está bien. Si C no logró llegar a esperar () antes de que D llame a notificar (), tiene un punto muerto porque la señal se pierde si nadie la está esperando y el estado de la variable condicional aún está "desestablecido".

Ten mucho cuidado con esto.


Estoy bastante seguro de que estás buscando variables de condición. La respuesta aceptada a esta otra pregunta SO:Variables de condición en C#, parece confirmarlo.

Véase, por ejemplo. este tutorial para obtener detalles sobre las variables de condición en hilos POSIX.


Un AutoResetEvent es más parecido a un semáforo binario. Las personas que dicen "variables condicionales" no están equivocadas per se, pero las variables de condición se usan en situaciones similares, en lugar de ser objetos similares. Puede implementar un AutoResetEvent (sin nombre) sobre las variables de condición:

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

Sin embargo, si necesita eventos de restablecimiento automático con nombre, es probable que desee ver los semáforos y puede tener un poco más de dificultad para traducir su código. De cualquier manera, miraría con cuidado la documentación de pthreads en su plataforma, las variables de condición y los eventos de reinicio automático no son lo mismo y no se comportan de la misma manera.


Linux
  1. ¿Cuál es el propósito del archivo .bash_profile en User Home Directory en Linux?

  2. ¿Cuál es el equivalente de Linux a la pausa de DOS?

  3. ¿Cuál es el equivalente a getch() y getche() en Linux?

  4. ¿Cuál es el equivalente Unix/Linux de E/S registrada?

  5. ¿Cuál es la ubicación de instalación convencional para aplicaciones en Linux?

¿Qué es el Shell en Linux?

¿Qué es el comando matar en Linux?

¿Cuál es el equivalente del comando de Linux sudo fdisk -l en MacOS?

¿Cuál es el equivalente de Active Directory en Linux?

¿Cuál es el equivalente Linux del inicio de Windows?

¿Cuál es el equivalente de FreeBSD de Linux update-rc.d?