4

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

4

1 回答 1

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++ 实现可能不是这种情况。

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

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

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

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

于 2012-12-26T14:55:28.690 回答