无法理解std :: thread的用法

时间:2013-09-07 12:01:58

标签: c++ c++11 stdthread

我正在阅读有关c ++ 11多线程的文档,并且遇到了std::thread的这个示例。

代码:

void thread_task(int n) {
  ...
}

int main(int argc, const char *argv[])
{
    std::thread threads[5];
    for (int i = 0; i < 5; i++) {
        threads[i] = std::thread(thread_task, i + 1);
    }

    return 0;
}

我不明白threads[i] = std::thread(thread_task, i + 1);std::thread是一个静态函数调用,并返回std :: thread对象的引用吗?听起来不可思议,但似乎是代码所说的。

因为我会这样写:

std::thread *threads[5];
for (int i = 0; i < 5; i++) {
    threads[i] = new std::thread(thread_task, i + 1);
}

感谢。

4 个答案:

答案 0 :(得分:13)

让我们详细了解正在发生的事情:

std::thread threads[5];

这将创建一个由5个std::thread个对象组成的数组,这些对象是默认构造的。目前它们代表“不是一个线程”,因为这是状态默认构造离开它们。

for (int i = 0; i < 5; i++) {
    threads[i] = std::thread(thread_task, i + 1);
}

这使用operator=的移动形式。由于线程不可复制,只能移动,thread& operator=(thread&& t)定义thread& operator=(const thread& t)。这会将threads[i]中的线程对象分配给新构造的std::thread(thread_task, i + 1);

这里没有理由使用指针数组。它只会增加内存泄漏的可能性。

答案 1 :(得分:2)

  

std::thread是否为静态函数调用,并返回std::thread对象的引用?

不,它正在创建一个临时线程对象;就像int(42)创建一个临时整数一样。赋值将其移动到数组中,因为线程是可移动的,并且临时值可以从中移动。

  

因为我会这样写:

您正在引入动态分配,额外的间接级别和内存泄漏(除非您在完成时添加代码以删除它们),这是没有充分理由的。

答案 2 :(得分:2)

std::thread的{​​{3}}创建一个代表线程的实例。作业是default constructor,因为也不允许复制。它将std::thread(thread_task, i + 1);创建的实例移动到数组中。

答案 3 :(得分:2)

此:

std::thread(thread_task, i + 1)

是对std :: thread构造函数的调用,它创建一个新的线程对象并向它传递一个指向thread_task函数的指针,该函数本身是以i + 1作为参数调用的。

赋值是移动赋值(因为右侧是指匿名对象),而不是复制赋值。请注意,将删除std :: thread复制构造函数和复制赋值运算符。

这实际上比使用指针更简洁,因为当线程数组超出范围时,std :: thread对象将被自动销毁。