2013-07-04 3 views
1

Я хочу узнать больше о std :: thread и, в частности, что произойдет, если у меня есть вектор потоков, и один из потоков завершит выполнение.Что происходит с потоком в векторе, когда заканчивается выполнение функции?

Изображение в этом примере:

Вектор нитей создается, что все выполняют следующие функции:

function_test(char* flag) 
{ 
    while(*flag == 1) { // Do Something 
    } 
} 

«символ * флаг» указывает на флаг сигнализации функцию, чтобы остановить выполнение.

Скажем, например, вектор содержит 10 потоков, которые все исполняются. Затем флаг устанавливается на ноль для номера потока 3. (4-й поток в векторе, так как вектор начинается с нуля.)

Хорошая практика заключается в том, чтобы затем присоединиться к потоку.

vector_of_threads[3].join(); 

Сколько std :: threads будет содержать вектор? Могу ли я снова запустить готовый поток с той же функцией или даже с другой функцией?

Причина моего вопроса в том, что у меня есть вектор потоков, и иногда они должны прекратить выполнение, а затем выполнение «падает с конца» функции.

Одно из решений для перезапуска этой нити (предположим, возможно, неправильно?) - удалить этот элемент из вектора, а затем вставить новый поток, который затем начнет выполнение. Правильно ли это, поскольку, когда поток останавливается, он все еще будет внутри вектора? Я предполагаю, что это будет?

Редактировать

'function_test' не разрешено изменять какие-либо другие функции флаги. Флаги модифицируются своей функцией и вызывающей функцией. (Для целей этого представьте флаг, обеспечивающий связь между основным и потоком.)

Зафиксирует ли это проблему с расходом данных или это проблема?

ответ

4

Это не то, о чем вы просите, но flag должно быть atomic<char>* или у вас есть data race, т. Е. Неопределенное поведение. Кроме того, если он имеет значение true или false, я бы использовал atomic<bool>* и просто проверил if (*flag).

Что касается вашего актуального вопроса:

Сколько станда :: потоков будет вектор теперь содержит?

Он будет содержать то же число, что и ранее, но один из них больше не «соединяется», потому что он не представляет собой бегущий поток. Когда поток прекращает работу, он не волшебным образом изменяет вектор для удаления элемента, он даже не знает, что вектор существует! Единственное изменение, видимое в основном потоке, заключается в том, что вызов vector_of_threads[3].join() не будет блокироваться и будет немедленно возвращаться, потому что поток уже завершен, поэтому вам не нужно ждать, чтобы присоединиться к нему.

Вы можете стереть соединяемых std::thread из вектора и вставить новый, но другой альтернативы, чтобы назначить другую std::thread ему, что представляет собой новый поток выполнения:

vector_of_threads[3] = std::thread(f, &flags[3]); 

Теперь vector_of_threads[3] представляет собой текущую нить и снова «соединяется».

+0

Хорошо, отлично, не могли бы вы объяснить мне немного больше о гонке данных и как/почему это происходит? – user3728501

+1

@EdwardBird, один поток выполняет 'if (* flag == 1)', и в какой-то момент другой поток устанавливает 'flags [3] = 1', без синхронизации между этими потоками вы читаете и записываете в одну и ту же память где конфликт: это гонка данных. –

+0

Каждый поток имеет свой собственный независимый символ char * variable/flag. Ни один другой поток не изменит флаг других потоков. Я должен был упомянуть об этом - я отредактирую вопрос. – user3728501

Смежные вопросы