Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 启动c++;11带有lambda捕获局部变量的线程_Multithreading_C++11_Boost - Fatal编程技术网

Multithreading 启动c++;11带有lambda捕获局部变量的线程

Multithreading 启动c++;11带有lambda捕获局部变量的线程,multithreading,c++11,boost,Multithreading,C++11,Boost,我有一个相当基本的问题,但不确定它的来源:并发环境中的lambda捕获评估或boost文件系统库的滥用。 这是示例代码: #include <iostream> #include <vector> #include <thread> #include <boost/filesystem.hpp> using namespace std; using namespace boost::filesystem; void query(const st

我有一个相当基本的问题,但不确定它的来源:并发环境中的lambda捕获评估或boost文件系统库的滥用。
这是示例代码:

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

using namespace std;
using namespace boost::filesystem;

void query(const string filename)
{
    cout << filename << " ";
}

int main() {
    path p("./");
    vector<thread> thrs;

    for(auto file = directory_iterator(p); file != directory_iterator(); ++file)
    {
        thread th( [file] {query(file->path().string());} );
        thrs.push_back(move(th));
    }

    for (auto& t : thrs)
        t.join();

    return 0;
}
请注意争用条件-并非所有文件最终都会传递给线程函数(在此运行时,makefile丢失)。
通过提取局部变量中的参数,将循环体重写为:

    auto fn = file->path().string();
    thread th( [fn] {query(fn);} );
    thrs.push_back(move(th));
比赛条件从何而来
文件->路径().string()不是在创建线程时正确计算的吗

文件->路径().string()不是在创建线程时正确计算的吗

否。由于必须在新线程上调用
query
,因此必须在新线程上执行语句
query(file->path().string())
。所以它是在线程创建之后的某个时间执行的,当线程开始做一些事情时

您捕获了
文件
。句号

从概念上讲,它与:

string * j = new string ("hello");
thread th( [j] { cout << *j << std::endl; } );
*j = "goodbye";
th.join();
string*j=新字符串(“你好”);
线程th([j]{cout
文件->路径().string()不是在创建线程时正确计算的吗

不可以。由于必须在新线程上调用
query
,因此必须在新线程上执行语句
query(file->path().string())
。因此,它是在线程创建后的某个时间执行的,此时线程开始执行任务

您捕获了
文件
。期间

从概念上讲,它与:

string * j = new string ("hello");
thread th( [j] { cout << *j << std::endl; } );
*j = "goodbye";
th.join();
string*j=新字符串(“你好”);

线程th([j]{cout创建线程时,不会计算线程lambda函数中的代码,而是在执行线程时进行计算。根据操作系统的调度,这可能是创建线程后的任意时间

它不起作用的真正原因是,这意味着不可能复制它,请提前一个副本并再次使用旧副本。通过捕获,您正是在这样做。您可以修改程序以在创建线程之前提取路径并捕获它:

int main() {
    path p("./");
    vector<thread> thrs;

    for(auto file = directory_iterator(p); file != directory_iterator(); ++file)
    {
        thrs.emplace_back([path = file->path()] {query(path.string());});
    }

    for (auto& t : thrs)
        t.join();

    return 0;
}
intmain(){
路径p(“./”);
载体thrs;
对于(自动文件=目录迭代器(p);文件!=目录迭代器();++file)
{
thrs.emplace_back([path=file->path()]{query(path.string());});
}
用于(自动&t:thrs)
t、 join();
返回0;
}

创建线程时,不会计算线程lambda函数中的代码,而是在执行线程时进行计算。根据操作系统的调度,这可能是创建线程后的任意时间

它不起作用的真正原因是,这意味着不可能复制它,请提前一个副本并再次使用旧副本。通过捕获,您正是在这样做。您可以修改程序以在创建线程之前提取路径并捕获它:

int main() {
    path p("./");
    vector<thread> thrs;

    for(auto file = directory_iterator(p); file != directory_iterator(); ++file)
    {
        thrs.emplace_back([path = file->path()] {query(path.string());});
    }

    for (auto& t : thrs)
        t.join();

    return 0;
}
intmain(){
路径p(“./”);
载体thrs;
对于(自动文件=目录迭代器(p);文件!=目录迭代器();++file)
{
thrs.emplace_back([path=file->path()]{query(path.string());});
}
用于(自动&t:thrs)
t、 join();
返回0;
}

所有同时使用std::cout的线程…所有同时使用std::cout的线程。。。