c++ 11头的大多数基本并行化都失败了
Most basic parallelization with C++11 theads fail
我尝试使用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++编译器。只要确保正确使用它们(不要混合使用不同的库版本)。
- 如何使用OpenMP并行化此矩阵时间矢量运算
- 如何使用 MPI 的远程内存访问 (RMA) 功能并行化数据聚合?
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- 如何使用 OpenMP 并行化最近邻搜索
- Malloc 在使用线程并行化 SSH 调用时存在问题
- 如何使用 OpenMP 正确并行化 for 循环?
- 如何将矩阵的行随机复制到内存中的另一个矩阵的过程并行化?
- 是变量初始化失败吗?
- 如何使用 Pthreads 并行化图像翻转?
- 部分模板专用化失败
- MPI:反复并行化缓冲区
- 是否可以使用OpenMP并行化一个列表,该列表可以在每次迭代中添加新元素
- 如何在Visual Studio中并行化armadillo
- thread_local静态成员模板定义:初始化失败,GCC
- 嵌套循环 OpenMP 并行化、私有索引还是公共索引?
- 如何并行化增加循环的大小
- 在 C++ 中使用 OpenMP 并行化两个 for 循环不会提供更好的性能
- OpenMP C++:并行化 for 循环的负载不平衡
- OpenMP 条件并行化 - 并行部分中 if 子句的语法
- c++ 11头的大多数基本并行化都失败了