这种方式是线程安全的吗?

时间:2014-04-15 16:14:10

标签: multithreading thread-safety

我有旧的网络客户端程序。我正在尝试将其更改为多线程程序。

您能否告诉我您对以下 JobList 的线程安全性的看法?

原始流程(thread1)

//Initializing
bThread1Done = false;
bThread2Done = true

While (true)
{
…
If (bThread2Done) {
  bThread2Done = false;
  while (!JobList.empty())
  {
    JobList.pop_front();
    LocalJobList.push_back();
  }
  bThread1Done = true;
}
…
Process(LocalJobList);
}

新后台主题(主题2)

While (true)
{
…
Recv(sock);
If (bThread1Done) {
  bThread1Done = false;
  while (!RecvList.empty())
  {
    RecvList.pop_front();
    JobList.push_back();
  }
  bThread2Done = true;
}
}

3 个答案:

答案 0 :(得分:1)

如果这个伪代码实际上是C ++,那么NO - 它不是线程安全的。

例如,从一个访问修改变量的两个或多个线程访问变量是未定义的行为。您还可以在不同的线程中调用同一对象的成员函数,这可能也不是线程安全的。

答案 1 :(得分:0)

通过同步对象,您可以实现此功能。

通过:this link

答案 2 :(得分:0)

您的代码不是线程安全的....

使用互斥锁和信号量保护您的共享结构,因此在任何给定时间只有一个进程可以访问它。

其他信息 您的代码线程安全性取决于bThread2Done = true;等分配的编译器实现以及if (bThread2Done) {...之类的测试,具体取决于

  1. CPU架构和
  2. 编译器优化
  3. 可能会或可能不会以原子方式发生 - 像a=b;这样的分配可能不会在一个指令或一个周期内发生,因此另一个线程可能会读取非紧凑写入的数据。

    编译器优化可能会消除if (bThread2Done) {...中的实际测试,如果它能够确定变量从未在循环中设置...有提示你可以给编译器变量设置在外面可能需要的代码(易变)。

    此外,您的代码正在实现所谓的自旋循环,这意味着如果线程被锁定,线程将使CPU 100%忙碌,这对您的系统性能来说非常糟糕。