c++ 11头的大多数基本并行化都失败了

Most basic parallelization with C++11 theads fail

本文关键字:并行化 失败 11头 大多数 c++      更新时间:2023-10-16

我尝试使用c++ 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的选项?

总则:

为了防止多个线程同时使用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/c++对该标准的实现仍处于实验阶段)。

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

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

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

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

我知道你在同一台机器上使用了两个不同版本的gcc/g++编译器。只要确保正确使用它们(不要混合使用不同的库版本)。