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

Mik*_*ike 13 c++ multithreading pthreads segmentation-fault c++11

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

更新:还在构造函数的第一行添加了一个print语句(所以在pthread_create调用之前),甚至在segfault之前都没有打印但是构造函数确实使用了初始化列表,所以有可能导致它的原因吗?

这是构造函数:

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);
}
Run Code Online (Sandbox Code Playgroud)

和析构函数:

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);
}
Run Code Online (Sandbox Code Playgroud)

更新2:

好吧我明白了.我的print函数是原子的,同样cout用其他地方定义的extern命名空间作用域mutex 保护.我改为普通,cout并在ctor的开头打印.显然,在尝试访问它们之前,这些静态存储持续时间互斥体都没有被初始化.所以是的,这可能是凯西的答案.

我只是不打扰复杂的对象和静态存储持续时间.无论如何,这没什么大不了的.

Cas*_*sey 6

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

如果程序启动一个线程(30.3),则对于在不同转换单元中定义的变量的初始化,变量的后续初始化是未序的.否则,对于在不同转换单元中定义的变量的初始化,变量的初始化是不确定地排序的.如果程序启动一个线程,则对于每个其他动态初始化,后续无序的变量初始化都是无序的.

我解释"随后的无序初始化变量对于其他所有动态初始化都没有排序"意味着生成的线程无法访问任何变量,动态初始化在线程生成之前未初始化而不会导致数据争用.如果那个线程没有以某种方式同步main,你基本上是用手捂住眼睛在雷区跳舞.

我强烈建议你仔细阅读并理解3.6; 即使没有线程,它也是一个巨大的PITA,在main开始之前就做了很多.

  • 所以,这是类固醇的静态秩序惨败 (2认同)
  • @BЈовић这就像静态初始化命令惨败的Mechagodzilla版本. (2认同)