GNU/Linux >> Linux の 問題 >  >> Linux

Linux での AutoResetEvent に相当する C++ は何ですか?

条件変数は NOT です AutoResetEvent に相当します。それらはモニターに相当します。この違いは重要であり、適切に使用しないとデッドロックが発生する可能性があります:

C# プログラムの 2 つのスレッド A と B を想像してください。 A は WaitOne() を呼び出し、B は Set() を呼び出します。 A が WaitOne() の呼び出しに到達する前に B が Set() を実行しても、Set() によって AutoResetEvent() に送信されるシグナルは永続的であり、WaitOne() が実行されるまで設定されたままになるため、問題はありません。

C で、2 つのスレッド C と D を想像してください。C は wait() を呼び出し、D は notify() を呼び出します。 D が notify() を呼び出したときに C がすでに待機している場合、すべて問題ありません。 D が notify() を呼び出す前に C が wait() に到達できなかった場合、誰も待っていない場合にシグナルが失われ、条件変数のステータスがまだ「未設定」であるため、デッドロックが発生します。

これには十分注意してください。


条件変数を探していると確信しています。この他の SO の質問に対する受け入れられた回答:C# の条件変数 -- それを確認しているようです。

例を参照してください。 POSIX スレッドの条件変数の詳細については、このチュートリアルを参照してください。


AutoResetEvent は、バイナリ セマフォに最も似ています。 「条件変数」という言葉自体は間違っていませんが、条件変数は似たようなオブジェクトではなく、似たような状況で使用されます。条件変数の上に (名前のない) 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;
}

ただし、名前付きの自動リセット イベントが必要な場合は、セマフォを確認する必要があり、コードの変換に少し時間がかかる場合があります。いずれにせよ、あなたのプラットフォームの pthreads のドキュメントを注意深く見てみると、条件変数と自動リセット イベントは同じではなく、同じように動作しません。


Linux
  1. LinuxとUnix:違いは何ですか?

  2. 初心者に最適なLinuxディストリビューションは何ですか?

  3. Linuxのユーザーホームディレクトリの下にある.bash_profileファイルの目的は何ですか

  1. Registered I/O に相当する Unix/Linux は何ですか?

  2. Mac 用の Linux の updatedb コマンドに相当するものは何ですか?

  3. Windows の Linux の File コマンドに相当するものは何ですか?

  1. DOS の一時停止に相当する Linux は何ですか?

  2. Linux の Active Directory に相当するものは何ですか

  3. Linux update-rc.d に相当する FreeBSD は何ですか?