使用 C++11 线程强制线程之间的争用
Forcing race between threads using C++11 threads
刚刚开始使用C++11线程库进行多线程(以及一般的多线程(,并编写了简短的代码片段。
#include <iostream>
#include <thread>
int x = 5; //variable to be effected by race
//This function will be called from a thread
void call_from_thread1() {
for (int i = 0; i < 5; i++) {
x++;
std::cout << "In Thread 1 :" << x << std::endl;
}
}
int main() {
//Launch a thread
std::thread t1(call_from_thread1);
for (int j = 0; j < 5; j++) {
x--;
std::cout << "In Thread 0 :" << x << std::endl;
}
//Join the thread with the main thread
t1.join();
std::cout << x << std::endl;
return 0;
}
由于两个线程之间的竞争,我每次(或几乎每次(都期望得到不同的结果,我运行这个程序。但是,输出始终是:0
,即两个线程像顺序运行一样运行。为什么我得到相同的结果,有没有办法模拟或强制两个线程之间的竞争?
您的样本量相当小,并且在连续的 stdout 冲洗中有些自停。简而言之,你需要一个更大的锤子。
如果要查看实际争用条件的实际运行情况,请考虑以下事项。我特意添加了一个原子和非原子计数器,将两者发送到示例的线程。一些测试运行结果发布在代码之后:
#include <iostream>
#include <atomic>
#include <thread>
#include <vector>
void racer(std::atomic_int& cnt, int& val)
{
for (int i=0;i<1000000; ++i)
{
++val;
++cnt;
}
}
int main(int argc, char *argv[])
{
unsigned int N = std::thread::hardware_concurrency();
std::atomic_int cnt = ATOMIC_VAR_INIT(0);
int val = 0;
std::vector<std::thread> thrds;
std::generate_n(std::back_inserter(thrds), N,
[&cnt,&val](){ return std::thread(racer, std::ref(cnt), std::ref(val));});
std::for_each(thrds.begin(), thrds.end(),
[](std::thread& thrd){ thrd.join();});
std::cout << "cnt = " << cnt << std::endl;
std::cout << "val = " << val << std::endl;
return 0;
}
一些示例从上面的代码运行:
cnt = 4000000
val = 1871016
cnt = 4000000
val = 1914659
cnt = 4000000
val = 2197354
请注意,原子计数器是准确的(我运行在具有超线程的双核 i7 Macbook Air 笔记本电脑上,因此 4 倍线程,因此 400 万(。对于非原子计数器来说,情况并非如此。
启动第二个线程会产生大量的启动开销,因此它的执行几乎总是在第一个线程完成 for 循环后开始,相比之下,这几乎不需要时间。若要查看争用条件,需要运行耗时更长的计算,或者包括 I/O 或其他需要大量时间的操作,以便两个计算的执行实际上重叠。
相关文章:
- 用C++中的std::condition_variable将线程置于死锁中会有风险吗
- 并行块(线程清理器)之外的 OpenMP 中的争用条件;误报?
- C++:用IIFE线程初始化静态局部变量安全吗
- 设计低线程争用的多线程聊天服务器
- 尽管互斥锁,线程中的争用条件
- 线程清理器检测到数据争用,问题出在哪里?
- 什么保证两个不相关的线程中的不同不相关对象没有(不可避免的)争用条件?
- 争用条件 2 个线程交替
- 从多个线程写入内存区域是否会导致争用?
- 如何在同一个线程上用同一个互斥对象锁定两次
- 当只有一个线程写入 c++ 中的布尔变量时,是否存在争用条件
- 使用 C++11 线程强制线程之间的争用
- GCC 的 TSAN 报告了线程安全静态本地的数据争用
- 使用packaged_task和线程可能的数据争用
- 线程安全、无数据争用、无延迟的共享容器 (circular_buffer)
- 在线程争用下等待的最快方法
- Std::condition_variable线程争用
- C++线程争用条件模拟
- c++ 11 (c++线程净化)用原子排序非原子操作(误报?)
- std::映射多线程中奇怪的资源争用