2个线程的同步,如何实现? 我尝试开发一个C++软件,它有1个线程作为控制器(控制器),另外8个线程(子线程)将通过TCP/IP来发送/ReV。

2个线程的同步,如何实现? 我尝试开发一个C++软件,它有1个线程作为控制器(控制器),另外8个线程(子线程)将通过TCP/IP来发送/ReV。,c++,multithreading,C++,Multithreading,我的软件以循环方式运行: 在开始时,子线程在无限循环中运行,在循环中它们等待来自控制器的启动信号。如果他们被来自控制器的信号唤醒,他们将执行发送/接收过程。发出信号后,控制器将等待来自子线程的停止信号 完成发送/接收后,每个控制器将向控制器发送停止信号。如果控制器收到足够的停止信号(8个子线程的8个停止信号)。它将复制数据,然后再次启动流程(下一个循环) 为此,我从一个非常基本的步骤启动我的软件:控制器线程和一个子线程,而这个子线程不做任何事情。(如果一切顺利,我将继续): 换句话说,当子

我的软件以循环方式运行:

  • 在开始时,子线程在无限循环中运行,在循环中它们等待来自控制器的启动信号。如果他们被来自控制器的信号唤醒,他们将执行发送/接收过程。发出信号后,控制器将等待来自子线程的停止信号
  • 完成发送/接收后,每个控制器将向控制器发送停止信号。如果控制器收到足够的停止信号(8个子线程的8个停止信号)。它将复制数据,然后再次启动流程(下一个循环)
为此,我从一个非常基本的步骤启动我的软件:控制器线程和一个子线程,而这个子线程不做任何事情。(如果一切顺利,我将继续):

  • 换句话说,当子线程等待启动信号时,控制器向子线程发送启动信号
  • 在接收到启动信号后,子线程立即发回停止信号
我先执行这个软件1000次,有时运行良好,有时不正常,通常会冻结

我想知道为什么会发生这种情况

如需更好的解释,请参考我的代码:

#include "CxxUtilities/CxxUtilities.hh"
using namespace std;
CxxUtilities::Condition StartSignal;
CxxUtilities::Condition StopSignal;

// declare a class of tx_thread, open, alive, wait for signal from controller thread //
class ChildThread: public CxxUtilities::StoppableThread{
public:
  void run(){
    cout << "started tx_thread" << endl;
        while(!stopped){

      /* wait for signal from main thread */
      cout << "sub:wait for main...";
      StartSignal.wait();
      cout << "sub:done, \n";

      /* signal to main thread */
      StopSignal.signal();     
      cout << "sub:signal sent, \n";
    }

  }

};

int main(int argc, char* argv[]) {
    using namespace CxxUtilities;
    int i;
    int Events = atoi(argv[1]);

    // declear threads //
    ReadingThread* thread[20];
    thread[0] = new ReadingThread;
    thread[0]->start();
    usleep(1000);

    for (i=0; i<Events; i++){
      cout << "\nevent#" << i+1 << ", ";
      /* send start signal to sub thread */
      StartSignal.broadcast();
      cout << "main:signal sent, \n";

      /* wait for stop signal from sub thread */
       cout << "main:wait for sub ...";
      StopSignal.wait();      
      cout << "main:done, \n";
    }
    cout << endl;
}

因为僵局,天气很冷。一种可能发生这种情况的方法是,在设置条件之前,如果main调用
StopSignal.wait
,并锁定互斥锁。然后您的子线程调用
StopSignal.signal
,这将阻止等待互斥锁。因此,两个线程都被阻塞,等待另一个线程的操作

应在最短的时间内获得锁。在拥有锁时执行等待是自找麻烦。你需要重新构造它,这样等待就没有锁了。差不多

for (;;) {
    mutex.lock();
    bool done = /*check condition variable*/;
    mutex.unlock();
    if (done) break;
    sleep(1);
}
这将在访问受保护的条件变量时保持锁,然后在检查条件结果时释放它(允许其他线程访问条件)。睡眠是用来释放CPU资源的


这不是解决问题的唯一方法,但实施起来非常简单。

对不起,我对您的解释感到困惑。。。让我解释一下我的理解:-主线程在子线程调用signal()之前阻止互斥体调用wait()因此,互斥锁被锁定在主线程中,子线程无法将互斥锁锁定到调用信号()ả伊比图ấ是的。因为主线程已经获取了互斥体,所以子线程阻塞(等待)互斥体。亲爱的@1201programalam,您的意思是我们必须在wait()之前发送信号吗?如果那样的话,我认为这是没有道理的,对吗?这里也提到了[link]()在调用pthread_cond_wait()之前调用pthread_cond_signal()是一个逻辑错误。亲爱的,现在我真的很困惑,对不起,但我想你的评论可能是对的。但也许我也有一些误解。比方说,要调用wait()和signal(),我们必须先调用mutex.lock()。但是如果wait()在此之前发生,则互斥锁不是unlock(),因此signal()不能发生。但是我们也必须在调用信号()之前调用wait(),对吗?亲爱的,我找到了前面注释的答案pthread_cond_wait()阻塞调用线程,直到发出指定条件的信号。这个例程应该在互斥锁被锁定时调用,它会在等待时自动释放互斥锁。接收到信号并唤醒线程后,互斥锁将自动锁定以供线程使用。然后,程序员负责在线程使用完互斥锁后解锁互斥锁。
for (;;) {
    mutex.lock();
    bool done = /*check condition variable*/;
    mutex.unlock();
    if (done) break;
    sleep(1);
}