Ответ 1
Они все там. Они просто искалечены, потому что вывод консоли происходит в неопределенно случайных порядках.
В частности, посмотрите на конец первой строки вывода.
Я новичок в С++, и я изучал некоторые кросс-платформенные учебники потоков С++. Я смотрел на это: http://solarianprogrammer.com/2011/12/16/cpp-11-thread-tutorial/
и пытался выполнить следующий код:
#include <iostream>
#include <thread>
static const int num_threads = 10;
//This function will be called from a thread
void call_from_thread(int tid) {
std::cout << "Launched by thread " << tid << std::endl;
}
int main() {
std::thread t[num_threads];
//Launch a group of threads
for (int i = 0; i < num_threads; ++i) {
t[i] = std::thread(call_from_thread, i);
}
std::cout << "Launched from the main\n";
//Join the threads with the main thread
for (int i = 0; i < num_threads; ++i) {
t[i].join();
}
return 0;
}
Выход, который я получаю, следующий, и я не понимаю, почему:
[email protected]:~/Desktop$ ./ref
Launched by thread Launched by thread Launched by thread Launched by thread Launched by thread 201
Launched by thread 5
Launched by thread 6
4
Launched by thread 7
3
Launched by thread 8
Launched from the main
Launched by thread 9
Я понимаю, что цифры случайны каждый раз, но иногда я не получаю никаких номеров, и мне интересно, почему?
Они все там. Они просто искалечены, потому что вывод консоли происходит в неопределенно случайных порядках.
В частности, посмотрите на конец первой строки вывода.
все, что вам нужно сделать, это добавить мьютекс и заблокировать его в правильном положении:
std::mutex mtx;
-
void call_from_thread(int tid) {
mtx.lock();
-----------------------------------------------------------
std::cout << "Launched by thread " << tid << std::endl;
-----------------------------------------------------------
mtx.unlock();
}
-
mtx.lock();
-----------------------------------------------------------
std::cout << "Launched from the main\n";
-----------------------------------------------------------
mtx.unlock();
В IO (cout) есть условие гонки в
std::cout << "Launched by thread " << tid << std::endl;
На самом деле, нет гарантии для последовательности cout ( "Запущен по потоку", tid, std:: endl). И он ведет себя так:
std::cout << "Launched by thread " ;
cout<< tid ;
cout<< std::endl;
Вы можете изменить call_from_thread на:
void call_from_thread(int tid) {
std::cout << std::string("Launched by thread " + std::to_string(tid) + "\n");
}
Следующий пункт находится в
t[i] = std::thread(call_from_thread, i);
При создании потока во время создания будет вызываться функция call_from_thread.
Так что лучше перемещать
std::cout << "Launched from the main\n";
Перед
//Launch a group of threads
for (int i = 0; i < num_threads; ++i) {
t[i] = std::thread(call_from_thread, i);
}
Вы также можете использовать держатели:
mutex g_i_mutex; // protects cout
void call_from_thread(int tid) {
lock_guard<mutex> lock(g_i_mutex);
cout << "Launched by thread " ;
cout<< tid ;
cout<< std::endl;
}
Промывочный поток должен сделать трюк:)
Следующая строка: std::cout << "Launched by thread " << tid << std::endl;
Изменить на: std::cout << "Launched by thread " << tid << std::endl << std::flush;