English 中文(简体)
C++ 在循环打印错误值的 C++ 线索
原标题:C++ threads inside a for loop print wrong values

我试图理解 C++ 中的多行,但我被困在这个问题中:如果我在 < em> 环中为 < / em > 启动线条,它们打印错误的值。 这是代码 :

#include <iostream>
#include <list>
#include <thread>

void print_id(int id){
    printf("Hello from thread %d
", id);
}

int main() {
    int n=5;
    std::list<std::thread> threads={};
    for(int i=0; i<n; i++ ){
        threads.emplace_back(std::thread([&](){ print_id(i); }));
    }
    for(auto& t: threads){
        t.join();
    }
    return 0;
}

我本来期望得到打印值 0,1,2,3,4,4,4,4,4的打印,但我经常得到同样的值两次。这是输出:

Hello from thread 2
Hello from thread 3
Hello from thread 3
Hello from thread 4
Hello from thread 5

我错过了什么?

最佳回答

[ & amp;] syntax 导致 > < i 被引用 < em> 捕获。 因此,当线条运行超过你预期时,通常会进一步推进 < code> < /code> 。 更严重的是, 如果 < code> > i 在线条运行前超出范围, 您的代码的行为是 < em > 未定义 < /em > 。

按值获取 > - 即 std:::\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

问题回答

有两个问题:

  1. 您无法控制线索运行的时间, 也就是说, libda 中的变量 < code> > < /code> 的值可能不是您所期望的 。

  2. 变量 > i 仅对循环和循环是本地的。如果循环在一个或多个线索运行之前完成,这些线索将无效地引用寿命结束的变量。

您可以通过捕获变量 > i by value 而不是引用 来非常简单地解决这两个问题。 这意味着每串线索都将拥有该值的 copy , 而该副本将为每条线索独家制作 。

还有一件事:

不要等到总有一个命令序列:0, 1, 2, 3,......, 因为多行执行模式有特殊性 : < 坚固 > 确定性 < / 坚固 > 。

不确定意味着在同样条件下执行同一方案会产生不同的结果。

这是因为操作系统时间表线因执行而异,视几个参数而定:CPU负荷、其他流程的优先次序、可能的系统中断等。

您的示例只包含五个线条, 所以它很简单。 尝试增加线条数量, 比如在处理函数中做一个睡眠。 你会看到结果会从一个执行到另一个执行的不同 。

使用 c++17 您可以做 :

void foo(int param)
{
  //something
}

main()
{
    std::vector<std::thread> threadList;

    for (int i = 0; i < 100; i++)
    {
        threadList.push_back( std::thread(foo, 2) );

    }
    
    for (auto& thread : threadList)
    {
        thread.join();
    }
}




相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?