В C ++ 11 какой смысл потока, который "не представляет поток выполнения"? - PullRequest
41 голосов
/ 26 сентября 2011

Просматривая новую многопоточность в C ++ 11, чтобы увидеть, как легко она отображается в pthreads, я заметил любопытный раздел в области конструктора thread:

нить ();
Эффекты: Создает объект потока, который не представляет поток выполнения.
Постусловие: get_id () == id ()
Броски: Ничего.

Другими словами, конструктор по умолчанию для потока на самом деле, кажется, не создает поток. Очевидно, он создает объект потока , , но как именно это полезно, если для него нет кода поддержки? Есть ли какой-то другой способ, которым "поток выполнения" может быть присоединен к этому объекту, например thrd.start() или что-то подобное?

Ответы [ 4 ]

36 голосов
/ 26 сентября 2011

Есть ли какой-нибудь другой способ, которым "поток выполнения" может быть присоединен к этому объекту, например thrd.start () или что-то подобное?

// deferred start
std::thread thread;

// ...

// let's start now
thread = std::thread(functor, arg0, arg1);

std::threadявляется типом MoveConstructible и MoveAssignable.Это означает, что в коде, подобном std::thread zombie(some_functor); std::thread steal(std::move(zombie)); zombie, будет оставлено специальное, но допустимое состояние, связанное с отсутствием потока выполнения.Конструктор по умолчанию поставляется в каком-то смысле свободным, поскольку все, что ему нужно сделать, это поместить объект в это точное состояние.Он также допускает массивы std::thread и такие операции, как std::vector<std::thread>::resize.

18 голосов
/ 26 сентября 2011

Это означает то же самое, что и это:

 std::vector<int> emptyList;

emptyList пусто.Точно так же как построенный по умолчанию std::thread.Точно так же как построенный по умолчанию std::ofstream не открывает файл.Существуют вполне разумные причины иметь классы, которые по умолчанию конструируют себя в пустое состояние.


Если у вас есть пустой поток:

std::thread myThread;

Вы можете фактически запустить поток, выполнивthis:

myThread = std::thread(f, ...);

Где f - это какая-то вызываемая вещь (указатель на функцию, функтор, std::function и т. д.), а ... - аргументы, которые должны быть переданы потоку.

8 голосов
/ 26 сентября 2011

Не просто гадание:

"объект потока" относится к std::thread.

"поток выполнения" относится к коллекции аппаратных регистров ОС , которые представляют поток.

C ++ 11 не делает ничего, кроме того, чтобы документировать API операционной системы для доступа к потокам ОС, чтобы сделать потоки C ++ переносимыми для всех ОС.

thread ();
Эффекты: Создает объект потока, который не представляет поток выполнения.
Постусловие: get_id () == id ()
Броски: Ничего.

Это означает, что значение по умолчанию std::thread не относится к потоку выполнения, созданному ОС.

A std::thread может быть присвоено новое значение, и поэтому он начинает ссылаться на поток выполнения ОС с помощью оператора присваивания перемещения:

std::thread t;  // Does not refer to an OS thread
//...
t = std::thread(my_func);  // t refers to the OS thread executing my_func
3 голосов
/ 26 сентября 2011

Просто угадай, но это просто означает, что поток не запущен. Другими словами, это просто объект, похожий на любой другой - за ним не обязательно находится реальный поток ОС. Иными словами, если потоки были реализованы поверх pthreads, создание объекта потока C ++ 11 не обязательно вызывает pthread_create () - это необходимо только при запуске потока.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...