gpt4 book ai didi

c++ - 是否允许主线程在进入 main() 之前生成 POSIX 线程?

转载 作者:IT老高 更新时间:2023-10-28 23:01:53 25 4
gpt4 key购买 nike

我有一个包含线程的对象。我希望对象的命运和线程的命运是一回事。因此构造函数创建一个线程(使用pthread_create),析构函数执行操作以使线程在合理的时间内返回,然后加入线程。只要我不使用静态存储持续时间实例化这些对象之一,它就可以正常工作。如果我在全局或命名空间或静态类范围内实例化这些对象之一,则程序编译良好(gcc 4.8.1)但在运行时立即出现段错误。使用打印语句,我确定主线程在段错误之前甚至没有进入 main() 。有什么想法吗?

更新:还在构造函数的第一行添加了一个打印语句(所以在调用 pthread_create 之前),甚至在段错误之前没有打印,但是构造函数确实使用了初始化列表,所以可能是什么原因造成的?

这里是构造函数:

worker::worker(size_t buffer_size):
m_head(nullptr),m_tail(nullptr),
m_buffer_A(operator new(buffer_size)),
m_buffer_B(operator new(buffer_size)),
m_next(m_buffer_A),
m_buffer_size(buffer_size),
m_pause_gate(true),
m_worker_thread([this]()->void{ thread_func(); }),
m_running(true)
{
print("this wont get printed b4 segfault");
scoped_lock lock(worker_lock);
m_worker_thread.start();
all_workers.push_back(this);
}

和析构函数:

worker::~worker()
{
{
scoped_lock lock(worker_lock);
auto w=all_workers.begin();
while(w!=all_workers.end())
{
if(*w==this)
{
break;
}
++w;
}
all_workers.erase(w);
}

{
scoped_lock lock(m_lock);
m_running=false;
}

m_sem.release();
m_pause_gate.open();

m_worker_thread.join();

operator delete(m_buffer_A);
operator delete(m_buffer_B);
}

更新 2:

好的,我想通了。我的打印功能是原子的,同样使用在其他地方定义的外部命名空间范围互斥锁来保护 cout。我改为纯 cout 并打印在 ctor 的开头。显然,在尝试访问它们之前,这些静态存储持续时间互斥锁都没有被初始化。所以是的,这可能是凯西的答案。

我只是不想为复杂的对象和静态存储持续时间而烦恼。反正也没什么大不了的。

最佳答案

C++11 §3.6.2 中描述了非局部变量的初始化,第 2 段中有很多可怕的东西与线程有关:

If a program starts a thread (30.3), the subsequent initialization of a variable is unsequenced with respect to the initialization of a variable defined in a different translation unit. Otherwise, the initialization of a variable is indeterminately sequenced with respect to the initialization of a variable defined in a different translation unit. If a program starts a thread, the subsequent unordered initialization of a variable is unsequenced with respect to every other dynamic initialization.

我解释“变量的后续无序初始化相对于所有其他动态初始化是无序的”意味着生成的线程无法访问具有动态初始化的任何变量,该动态初始化在线程生成之前未初始化而不会导致数据竞争.如果该线程无法以某种方式与 main 同步,那么您基本上是双手捂着眼睛在雷区中跳舞。

我强烈建议您通读并理解 3.6 的全部内容;即使没有线程,在 main 启动之前要做很多事情也是一个巨大的 PITA。

关于c++ - 是否允许主线程在进入 main() 之前生成 POSIX 线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21771066/

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