同时重启多个锁定线程

Posted

技术标签:

【中文标题】同时重启多个锁定线程【英文标题】:Concurrently restarting multiple locked threads 【发布时间】:2012-06-28 21:15:47 【问题描述】:

我目前有 N 个线程都是打开的 udp/tcp 连接。当我从任何线程中收到第一个数据包时,主线程(称为 N 线程)需要暂停 N 线程中的执行并在恢复 N 线程之前做一些工作。

我最初的想法是让所有 N 个线程使用一个公共互斥锁,该互斥锁等待来自主线程的 pthread_cond_broadcast。据我了解,所有 N 个线程将在调用广播时按调度程序确定的某种顺序恢复执行,因为它们都依赖于同一个互斥锁。但是,我需要它们并行恢复。

这基本上就是我的问题的样子:

主线程:

//create N threads. Each thread is connected to a different 
//location but uses the same code

//detect that one of the threads has received a packet
//tell all child threads to pause
pauseThreads();

//do some work on the first packet

resumeThreads();

//tell all child threads to resume

子线程代码:

while(true)
  recv() data


  //the other N-1 threads should ideally block here, 
  //since I'd like to process just the 
  //very first packet

  //hopefully pauseThreads() has been called by the main
  //thread by here if the first packet has been received.
  //All threads should block here until the main thread 
  //is done processing the first packet. Once it's done
  //processing, *firstPacket will be false and the if statement 
  //can be skipped over

  //only one thread should ever access this
  if(*firstPacket  /*this is a global variable*/  )
      //process first packet
      *firstPacket = false;
      //the thread that receives the first packet should block here
  

  //process same packet data in another format

线程需要同时重新启动的原因是速度是一个问题,我不能等待每个线程一个一个地完成自己的数据处理。我已经弄清楚了 if 语句中的阻塞,但是我想不出一种有效地阻塞 N-1 个线程的方法。

【问题讨论】:

为什么所有的线程?如果您试图将它们同步得如此紧密,以使它们表现得好像只有一个线程。然后考虑使用一个线程。 好吧,所有的连接都由同一个实体运行。数据通过不同的渠道广播,但都相互关联。如果我在一个线程中完成所有操作,我将无法跟上数据传入的速度。 我不明白前 2 个陈述,但关于跟上的第三个陈述。尽可能快:线程数的上限是每个处理器核心一个线程。最佳值通常较低。随着您描述的锁定量。无论处理器内核有多少,我都建议使用一个线程。 我的意思是,如果可以从 A-Z 标记数据 - A-B 在一个通道中,B-C 在另一个通道中,等等。所有数据都来自同一个服务,但必须分布在不同的通道中;即服务运行多个 udp 连接来广播其所有数据。如果调度程序必须选择自己的顺序,我的程序的效率会大大降低,因为我无法看到在不同单元中接收到的事物之间的实时关系。从本质上讲,事情需要根据来自服务的数据进行更新,延迟将是一件坏事。 (有很多核心。) 最好让服务器为 udp 数据包添加时间戳或序列号。或者,在接收器中,我假设您只有一个网络采用者,并且服务器和您之间只有一条路由,否则数据包可能会重新排序。所以现在我们需要在进一步处理之前对数据包进行时间/序列标记。为此使用单个线程。概括。让服务器提供帮助,或使用处理器群:第一个线程接收和时间戳,然后将任务的其余部分分配给工作线程。 【参考方案1】:

最佳

让服务器为 udp 数据包添加时间戳或序列号。

或者

在接收器中,我假设您只有一个网络适配器,并且服务器和您之间只有一个路由。否则数据包可能会被重新排序。

所以现在我们需要对数据包进行时间/序列标记,然后再进行进一步处理。为此使用单个线程,然后将任务的其余部分外包给工作线程。

【讨论】:

以上是关于同时重启多个锁定线程的主要内容,如果未能解决你的问题,请参考以下文章

初识多线程__下

iostream 线程安全,必须分别锁定 cout 和 cerr 吗?

如何动态锁定线程并避免竞争条件

线程基础

多个线程试图锁定

如果我们同时从向量中追加和读取数据,我们是不是需要锁定?(无修改)