我尝试使用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?
答案 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 ++编译器。请确保您正确使用它们(不要混合使用不同的库版本)。