使用C ++ 11 theads的大多数基本并行化失败

时间:2012-12-26 14:50:30

标签: c++ multithreading c++11 pthreads

我尝试使用g ++ 4.7使用C ++ 11主题库。 首先我有一个问题:是否预计下一个版本不需要手动链接pthread库?

所以我的节目是:

#include <iostream>
#include <vector>
#include <thread>

void f(int i) {
    std::cout<<"Hello world from : "<<i<<std::endl;
}

int main() {
    const int n = 4;
    std::vector<std::thread> t;
    for (int i = 0; i < n; ++i) {
        t.push_back(std::thread(f, i));
    }
    for (int i = 0; i < n; ++i) {
        t[i].join();
    }
    return 0;
}

我编译:

g++-4.7 -Wall -Wextra -Winline -std=c++0x -pthread -O3 helloworld.cpp -o helloworld

它返回:

Hello world from : Hello world from : Hello world from : 32
2
pure virtual method called

terminate called without an active exception
Erreur de segmentation (core dumped)

问题是什么以及如何解决?

更新:

现在使用互斥锁:

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>

static std::mutex m;

void f(int i) {
    m.lock();
    std::cout<<"Hello world from : "<<i<<std::endl;
    m.unlock();
}

int main() {
    const int n = 4;
    std::vector<std::thread> t;
    for (int i = 0; i < n; ++i) {
        t.push_back(std::thread(f, i));
    }
    for (int i = 0; i < n; ++i) {
        t[i].join();
    }
    return 0;
}

它返回:

pure virtual method called
Hello world from : 2
terminate called without an active exception
Abandon (core dumped)

更新2: 嗯...它适用于我的默认GCC(g ++ 4.6),但它失败了我手工编译的gcc版本(g ++ 4.7.1)。有没有选项我忘了编译g ++ 4.7.1?

1 个答案:

答案 0 :(得分:0)

常规编辑:

为了防止多个线程同时使用cout,这将导致字符交错,按以下步骤操作:

1)在声明f()之前声明:

static std::mutex m;

2)然后,保护“cout”之间的界限:

m.lock();
std::cout<<"Hello world from : "<<i<<std::endl;
m.unlock();

显然,出于一些不明原因,必须链接-lpthread库。至少在我的机器上,没有链接-lpthread导致核心转储。添加-lpthread会导致程序正常运行。

如果在从不同线程访问cout时未使用锁定,则表示字符交错的可能性如下所示:

https://stackoverflow.com/a/6374525/1284631

更确切地说:“[注意:如果用户希望避免交错字符,用户仍必须同步多个线程并发使用这些对象和流。 - 结束注释]”

OTOH,保证可以避免竞争条件,至少在C ++ 11标准中(注意,该标准的gcc / g ++实现仍处于实验级别)。

请注意,Microsoft实现(参见:http://msdn.microsoft.com/en-us/library/c9ceah3b.aspx归功于@SChepurin)比标准更严格(显然,它保证避免字符交错),但这可能不是gcc / g ++实现的情况

这是我用来编译的命令行(更新和原始代码版本,一切都在我的电脑上运行良好):

g++ threadtest.cpp -std=gnu++11 -lpthread -O3

OTOH,没有-lpthread,它编译但我有一个核心转储(Linux 64上的gcc 4.7.2)。

据我所知,您在同一台计算机上使用了两个不同版本的gcc / g ++编译器。请确保您正确使用它们(不要混合使用不同的库版本)。