在Cygwin

时间:2015-11-14 11:00:21

标签: c++ multithreading c++11 cygwin

我不确定std::thread是否应该在Cygwin下工作。我发现的唯一帖子是多年以来处理编译器错误。所以这个问题有点不同。

我正在将一个应用程序从Linux移植到Cygwin。它使用std::thread多个线程并且除了一件事之外有效:在一个地方,std::thread::detach()的调用会引发Invalid argumentstd::thread::joinable()会返回true

我试图建立一个例子:

#include<thread>
#include<iostream>
#include<mutex>
#include<condition_variable>

std::thread* t;
std::mutex m;
std::condition_variable cv;

void func(void)
try
{
    std::cout << "func" << std::endl;
    if (t->joinable())
    {
        std::cout << "t is joinable" << std::endl;
        t->detach();
        delete t;
        std::unique_lock<std::mutex> lck(m);
        cv.notify_all();
    }
}
catch(std::exception& e)
{
    std::cout << "exception in func: " << e.what() << std::endl;
}


int main(void)
{
    try
    {
        std::unique_lock<std::mutex> lck(m);
        t=new std::thread(&func);
        cv.wait(lck);
        std::cout << "func finished" << std::endl;
        cv.wait(lck);
    }
    catch(std::exception& e)
    {
        std::cout << "exception in main: " << e.what() << std::endl;
    }

    return(0);
}

我在Linux上使用

编译它
g++ -std=c++0x -pthread example.cc

使用gcc版本4.6.3。它产生

func
t is joinable
func finished

然后每次无限期挂起,这是由于对cv.wait()的第二次无法匹配的调用而导致的预期行为。

在Cygwin上我用

编译
g++ -std=c++11 -pthread example.cc

使用gcc版本4.9.3

它有时显示上述行为,有时它只显示

func

然后以0退出。

所以我无法重现我原来的错误,而是得到一些更不稳定的行为。

2 个答案:

答案 0 :(得分:1)

您发布的程序包含未定义的行为。有两个线程(mainfunc)竞争访问t(这是普通的非原子指针)。

包含未定义行为的程序会包括(但不限于)鼻子恶魔。所以linux和cygwin似乎都在这个意义上起作用,只是鼻子里的恶魔恰好是不同的类型。

答案 1 :(得分:1)

首先,你可能是虚假醒来的受害者......

允许实现唤醒条件变量,因此您有责任确保满足条件......您可以通过向cv.wait()提供额外参数来实现此目的

请参阅:http://www.cplusplus.com/reference/condition_variable/condition_variable/wait/

其次,只将“func”作为输出,退出零(0)让我担心。因此根本不应该发生。

至少应该打印“func has finished”,因为你刷新了流:std :: endl;