2011-09-26 10 views
37

Patrząc na nowego gwintowania rzeczy w C++ 11, aby zobaczyć, jak łatwo to mapuje pthreads, zauważam ciekawy rozdział w dziedzinie thread Konstruktor:W C++ 11, jaki jest sens wątku, który "nie reprezentuje wątku wykonania"?

wątku();
Efekty: Konstruuje obiekt wątku, który nie reprezentuje wątku wykonania.
Postcondition: get_id() == id()
Rzuty: nic.

Innymi słowy, konstruktor domyślny dla wątku faktycznie nie wydają się tworzyć nitki. Oczywiście tworzy obiekt wątku ,, ale jak dokładnie jest to przydatne, jeśli nie ma dla niego kodu wstecznego? Czy istnieje inny sposób, w jaki "wątek wykonania" może być dołączony do tego obiektu, np. thrd.start() lub coś podobnego?

+0

C++ 11 straszenia ciebie i mnie zarówno w tym momencie, na szczęście jestem teraz deweloperem jądra, więc standardy już mnie nie zmieniają :) –

+5

Myślę, że to znaczy, że konstruktor wątku nie tworzy aktualnego wątku, nie wywołuje systemu operacyjnego, nie przydziela stosu/inne zasoby i generalnie nie tworzy zatrzymanego wątku. Myślę, że to jest na miejscu, aby ludzie wiedzieli, że nie marnują niczego, tworząc wątek przed jego uruchomieniem (poza przechowywaniem flag). – Dani

+5

@Jesus Ramos: kernel dev przestraszony od standardowych zmian? Jeśli dobrze pamiętam, każdy nowy procesor rozbija coś w jądrze lub dodaje funkcję, która wymaga wiele przeróbek do implementacji. – Dani

Odpowiedz

34

Czy istnieje inny sposób, w jaki "wątek wykonania" może być dołączony do tego obiektu, jak thrd.start() czy coś podobnego?

// deferred start 
std::thread thread; 

// ... 

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

std::thread jest MoveConstructible i MoveAssignable typu. Oznacza to, że w kodzie takim jak std::thread zombie(some_functor); std::thread steal(std::move(zombie));zombie pozostanie w specjalnym, ale prawidłowym stanie skojarzonym z żadnym wątkiem wykonania. Domyślny konstruktor jest wolny w pewnym sensie, ponieważ wszystko, co musi zrobić, to umieścić obiekt w tym dokładnym stanie. Umożliwia także tablice o wartości std::thread i operacje takie jak std::vector<std::thread>::resize.

+0

W rzeczywistości ... Twój wątek będzie miał identyfikator wątku równy 0. Nie ma wewnętrznego kontekstu wątku macierzystego. To tylko typ zastępczy dla tablic i kontenerów STL. – Noishe

3

Po prostu zgaduję, ale to po prostu oznacza, że ​​wątek nie został uruchomiony. Innymi słowy, jest to po prostu obiekt jak każdy inny - niekoniecznie jest to rzeczywisty wątek systemu operacyjnego. Innymi słowy, jeśli wątki zostały zaimplementowane na elementach pthreads, tworzenie obiektu wątku C++ 11 nie musi wywoływać pthread_create() - to musi się zdarzyć tylko po uruchomieniu wątku.

+0

Więc, ... moje zapytanie byłoby drugą częścią mojego pytania: "jak zacząć?" – paxdiablo

+0

Może nie możesz. W końcu, jeśli użyłeś konstruktora zerowego argumentu, nic nie określono dla wątku na * do *. To, jak przypuszczam, prowadzi do pytania, dlaczego można stworzyć taki bezużyteczny obiekt. – davmac

+0

Raczej: Jak Luc Danton wskazuje w swojej odpowiedzi poniżej, możesz użyć operatora przypisania, aby rozpocząć wątek. – davmac

18

Oznacza to samo jak to:

std::vector<int> emptyList; 

emptyList jest pusty. Podobnie jak domyślnie skonstruowany std::thread. Tak jak domyślnie skonstruowany std::ofstream nie otwiera pliku. Istnieją całkowicie uzasadnione powody, dla których klasy domyślnie konstruują się w stan pusty.


Jeśli masz pusty wątek:

std::thread myThread; 

Można zacząć wątek w ten sposób:

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

Gdzie f pewne wywoływalnym rzecz (wskaźnik funkcji, funktor, std::function, itp.) I ... są argumentami do przekazania do wątku.

8

Nie tylko zgadywać:

"obiekt wątek" odnosi się do std::thread.

"Wątek wykonania" odnosi się do OS's collection of hardware registers that represent a thread.

C++ 11 nie robi nic poza programowaniem interfejsu API systemu operacyjnego w celu uzyskania dostępu do wątków systemu operacyjnego w celu umożliwienia przenoszenia C++ na wszystkie systemy operacyjne.

wątek();
Efekty: Konstruuje obiekt wątku, który nie reprezentuje wątku wykonania.
Postcondition: get_id() == id()
Rzuty: nic.

Oznacza to, że domyślnie skonstruowany std::thread nie odnosi się do wątku wykonania, który został wyprodukowany przez system operacyjny.

std::thread można nadać nową wartość, a tym samym zaczynają odnosić się do wątku OS wykonania przez instrukcji przypisania ruch:

std::thread t; // Does not refer to an OS thread 
//... 
t = std::thread(my_func); // t refers to the OS thread executing my_func