gpt4 book ai didi

c++ - Boost Threads - 赛车

转载 作者:行者123 更新时间:2023-11-30 00:59:12 24 4
gpt4 key购买 nike

我正在玩一些 Boost 线程,我编写了以下代码:

#include <boost/thread.hpp>
#include <iostream>

volatile int threads = 0;

const int iterations = 200;

volatile char output[iterations*4];
volatile int k = 0;

void w() {
threads++;
for (int i = 0; i < iterations; i++) {
k++;
output[k] = '0';
}
}
void y() {
threads++;
for (int i = 0; i < iterations; i++) {
k++;
output[k] = '1';
}
}

int main(int argc, char* argv[]) {
boost::thread a(&w);
boost::thread b(&w);
boost::thread c(&y);
boost::thread d(&y);

while (k <= iterations * 4) {}

for (int i=0; i < k; i++) {
std::cout << output[i];
}
return 0;
}

我不明白的是为什么这些线程的完成看起来像是在等待彼此,这在输出中显示:

000000000000000000000000000000000000000011111111

我的印象是输出是随机顺序的,语句输出类似于以下内容(预期输出):

00100000111001000000010001111100000000011111111

相反,它们紧随其后,全为 0,然后全为 1(反之亦然)。

这是为什么?在这一点上,线程似乎更像是以随机顺序堆叠,但仍然连接在一起;即在执行之前互相等待。我实际上希望 threads++ 代码可能在某些线程中同时运行,并为它们留下一些 thisthread 值。

免责声明:我是 Boost:threads 的新手,只是玩玩,我知道竞争条件非常危险(可能导致未定义的行为),这只是把我的手放在火里所以我可以理解它。

最佳答案

这里有几件事阻止您看到您期望的上下文切换行为:

  1. 线程基本上处于紧密循环中。中间不太可能发生上下文切换。
  2. w(2) 打印 6,然后打印 47 时,您的示例中确实有一个奇怪的上下文切换。它从 3 切换到 2,然后再切换回来。
  3. C++ 编译器可能优化了对全局变量的访问。使变量 volatile 可能会有所帮助。请注意,volatile 并不是真正的解决方案。例如,增量可能不是原子操作(也称为获取、增量、存储),而且 CPU 缓存有时会导致奇怪的伪影,因为存储到内存的操作在执行时不会被所有 CPU 看到。
  4. 您没有使用endl。通常,我认为 endl 是一个绝对可怕的想法。但在这种情况下,这意味着所有写入都被缓冲,这可能会导致一些有趣的伪影。
  5. 此外,cout 将是线程安全的,实现这一点所需的锁也可能会影响线程上下文相互切换的方式。

其中的一些问题可以通过直接调用write 系统调用来解决。这将强制执行系统调用,这可能会给另一个线程运行的机会。它还将强制输出恰好在执行它的代码时发生。

这是一个程序,它将展示您在多核 Unix 机器上寻找的行为。它还将向您显示 k 的最终值,以说明为什么 volatile 并不是真正的解决方案,以及它如何在值 k 上引发竞争。我最初只是建议将其作为 hack 来让您的程序更好地工作以产生您正在寻找的行为,因为在您的原始程序中它并不重要:

#include <boost/thread.hpp>
#include <iostream>
#include <unistd.h>

volatile int threads = 0;

const int iterations = 200;

volatile int k = 0;

void w(char thid) {
threads++;
for (int i = 0; i < iterations; i++) {
k++;
::write(1, &thid, 1);
}
}

int main(int argc, char* argv[]) {
boost::thread a(&w, '0');
boost::thread b(&w, '1');
boost::thread c(&w, '2');
boost::thread d(&w, '3');

a.join();
b.join();
c.join();
d.join();
::write(1, "\n", 1);
// In general, do not mix write to stdout and cout. In this case
// it will work, but this is a very limited and specific case.
::std::cout << "k == " << k << "\n";
return 0;
}

关于c++ - Boost Threads - 赛车,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4848124/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com