创建的线程比预期的要多
More threads created than expected
您可以在此处找到程序
我正在在消息传递框架0MQ中构建一个程序。我尝试实现我在此处发布的内容
用g++ -std=c++11 test.cpp -o test -lzmq -lpthread
编译的程序。
要运行程序,请将一个参数作为您想要的线程编号传递。然后将该参数分配给变量worker_num
。
在主线程中,我设置了:
vector<thread> pool;
for(int i = 0; i < worker_num; i++)
{
cout << "main() : creating thread, " << i << endl;
pool.push_back(thread(task1, (void *)&context, i));
}
我想确保所有工作线程都成功地连接到主线程,然后在主线程向其分发作业。
while(true)
{
if(sync_done)
{
cout << "sync done in main thread" << endl;
break;
}
zmq::message_t sync_msg(4);
memcpy((void *)sync_msg.data(), SYNC_MSG, SYNC_MSGLEN);
for(int i = 0; i < worker_num; i++)
distask_socket.send(sync_msg);
for(int i = 0; i < worker_num; i++)
{
if(sync_done)
break;
if(i != 0)
this_thread::sleep_for(chrono::milliseconds(500));
zmq::message_t res_msg;
int ret = getres_socket.recv(&res_msg, ZMQ_DONTWAIT);
if(ret == -1 && errno == EAGAIN)
continue;
int threadID = stoi(string((char *)res_msg.data()));
sync_done = if_sync_done(threadID, sync_array, worker_num);
}
}
主线程的作用是:按下sync
msg的#worker_num,其推动端点每次推动端点,然后从其拉力端点读取确认msg。如果主线程检索#worker_num确认msgs,则同步完成。来自Worker的同步MSG的格式为:String中的Worker线程ID。因此,线程0将通过字符串中的0
传递回主线程。
但是运行我拥有的程序:
$ ./test 1
main() : creating thread, 0
thread id:0
thread 0 receives: sync
thread 0 sends: 0
thread 0 sync done
main thread receives sync msg from thread 1 # you may get many copies of this msg
terminate called after throwing an instance of 'std::invalid_argument'
what(): stoi
Aborted
main thread receives sync msg from thread 1
表示线程是创建2个线程的线程:线程0和线程1。任何想法为什么?我确实将1
作为参数传递。注意,如果您自己运行程序,则可能会获得其他输出。
更新:
程序更新:此处。
终于我弄清楚了什么问题。
预期输出,您看到线程0将0
传递到主线程以通知同步完成:
$ ./test 1
input parameter is: 1
main() : creating thread, 0
thread 0 receives: sync
to_string 0
thread 0 sends: 0, with size: 1
thread 0 sync done
pass 0 to if_sync_done
main thread receives sync msg from thread 0
sync done in main thread
意外的输出,您看到无法打印的char传递给 stoi()
:
$ ./test 1
input parameter is: 1
main() : creating thread, 0
thread 0 receives: sync
to_string 0
thread 0 sends: 0, with size: 1
thread 0 sync done
pass to if_sync_done # !!!!!
terminate called after throwing an instance of 'std::invalid_argument'
what(): stoi
Aborted
因此,我似乎错误地使用了message_t
。因此,我需要确保在主线程将内容传递给stoi()
之前,缓冲区仍然存在。
我会自己添加答案。
zmq::message_t msg_back((void *)to_string(id).c_str(), to_string(id).size() + 1, NULL);
zmq::message_t
构造函数您使用不是如果相信[1]和[2],则可以复制缓冲区的副本。相反,它需要缓冲区的所有权。
但是,您正在通过临时管理的缓冲区;构造函数返回后,该缓冲区将立即销毁。您的msg_back
存储了一个悬空的指针。任何尝试使用该指针的尝试 - 例如试图在接收端读取消息 - 表现出未定义的行为。
- 两个线程一个使用流 Api,另一个线程创建文件失败并出现错误ERROR_SHARING_VIOLATION
- C++ 线程创建/删除与线程停止/恢复
- Qt - 如何从线程创建 QFuture
- 我可以使用Qt线程ID为每个线程创建唯一的缓存吗?
- 零MQ 后台线程创建
- OpenMP 线程创建
- GLFW & ImGui:从 main 以外的线程创建 ImGui 控件
- 对象:无法为位于不同线程中的父线程创建子级
- C++ 11:线程创建给我一个"Attempt to use a deleted function"错误
- C 的周期性线程创建
- MPI - 当数组初始化值必须为常量时,如何为工作线程创建部分数组
- 当主GUI线程被阻塞时,如何从工作线程创建无模式对话框
- 多个线程创建5个线程来计算质数
- 为线程创建模板
- 线程创建,CRT和DLL是如何完成的?
- 同步线程创建和销毁(静态)对象
- 竞争条件:一个线程创建静态对象,另一个线程在初始化完成之前使用它.如何处理
- 从不同线程创建QMainWindow
- QFuture 无法为位于不同线程中的父线程创建子级
- ( QNativeSocketEngine)QObject:无法为位于不同线程中的父线程创建子级