gpt4 book ai didi

c++ - 如何有效地将偶尔遇到的参数传递给子线程?

转载 作者:太空狗 更新时间:2023-10-29 21:33:27 28 4
gpt4 key购买 nike

我想将字符串参数传递给子线程(持续读取套接字)并调用 setsockopt()在该套接字上使用该参数。

我正在使用 ZeroMQ 套接字,所以调用 setsockopt()not threadsafe在这里,我会调用 setsockopt()来自子线程(推荐 here )。参数更新可能在数十亿次读取周期中只发生一次,添加 if 感觉有点不对劲。 - 像这样构造 child 的每个周期:

bool new_arg_available;
std::string new_arg;

while(1){
sub_socket->recv(data); // . . . . . . a blocking method call
printData(data)

... // . . . . . . data can set new_arg_available

if (new_arg_available){ // . . . . . . synchronization goes here
sub_socket->setsockopt(ZMQ_SUBSCRIBE, new_arg, ... );
new_arg_available = false;
}
}

对我来说,最直接的可能是:

  1. 在全局命名空间中添加一个互斥量,当出现 new_arg 时将其锁定在父线程中可用,并从子线程中解锁。

  2. 使用 std::atomic<bool>和1一样使用。

但是,我想以某种方式实现的是让 child 可以被打断,这样我就可以消除 if -结构从while(){...}的末尾开始堵塞。我不介意上下文切换的惩罚,因为这种事件很少见。

我是 C++ 的新手,我想了解这里的最佳实践,了解如何以有效的方式实现这一目标。我想在不使用 Boost 的情况下解决它,我能找到的实现可中断线程的唯一示例是使用 Boost。

最佳答案

欢迎来到零禅之地

关于 ZeroMQ 宣传的主要评论是,ZeroMQ 作者从那时起就提倡避免任何类型的共享 - 零共享。

鉴于您已经实例化了 ZeroMQ 基础设施,最好在无 IO 线程 inproc 上使用线程间 PUSH/PULL:// 传输类并忘记任何棘手的 (b-) 锁定。

一侧(注入(inject)器)只是 aPushCHANNEL.send( new_arg );
和另一个(实现者)只是aPullCHANNEL.recv()-s as needed/when needed, or may use smarter means of aPullCHANNEL.poll()-testing,如果使用轮询测试的零等待形式再次最好 if aPullCHANNEL.poll( 0 ){...}else{...}

还有你的架构变成了一个完全分解的、基于多代理角色的干净和智能的,没有任何肮脏的死锁(所以最好从一开始就忘记 REQ/REP ),没有任何难以追踪/调试的概念缺陷和所有在适用的情况下检测到错误,并且在本地责任有意义的情况下映射任何此类错误的根本原因以进行即时错误处理。


注意: 是的,ZeroMQ 从一开始就被设计为不需要线程安全,因为没有任何东西可以共享(零共享)。 API v4.1+ 中的一些最近的努力开始从这个零禅开始下降,所以人们可能会读到线程安全的某些方面,但正如上面提到的,并且几乎出现在神话般的 Pieter HINTJENS 的 ZeroMQ 的每一页上圣经书 - “Code Connected, Volume 1” - 最好什么都不分享。

ZeroMQ 设计是完全异步的,不需要关心锁定、互斥体操和其他形式的外部引入的元素,在一个干净、智能的基于多代理异步信号/消息传递的基础上 建筑学。你会爱上它的,所以继续尝试并阅读这本书。这将是艰难的,但它会为那些将继续并发现 ZeroMQ 零禅之美的人付出很多。

关于c++ - 如何有效地将偶尔遇到的参数传递给子线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51029729/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com