#c #multithreading #pthreads
#c #многопоточность #pthreads
Вопрос:
Я хочу создать N потоков, которые выполняют функцию, я сделал это следующим образом
for (int p = 0; p < threads; p )
pthread_create(amp;tid[p], NULL, dowork, full);
на данный момент я использовал
for (int p = 0; p < threads; p )
pthread_join(tid[p], NULL);
чтобы снова создать n потоков, но я хочу создать другой поток, когда завершится один из созданных потоков.
Например, у меня есть 3 потока для выполнения 6 заданий (запуск одной и той же функции 6 раз с разными параметрами)
Я создаю 3 потока, если один из них завершает создание другого потока немедленно, не дожидаясь завершения всех из них.
Как я могу это сделать?
Комментарии:
1. Почему другой поток вместо того, чтобы каждый поток просто выполнял немного больше работы, а затем завершал?
2. Вроде бы это тоже нормально, но я не знаю, когда завершится конкретный поток
3. Проблема с join в том, что вы узнаете, когда они все будут выполнены, но если они закончатся не по порядку, у вас нет возможности узнать. Вместо того, чтобы усложнять этот код передачей сообщений между потоками и атомариями / мьютексами / блокировками, просто проделайте немного больше работы в каждом потоке и назовите это done.
4. Как только поток выполнен,
pthread_join
разблокируется. Таким образом, вы можете добавить другой поток для выполнения работы. Это просто, но вы можете не знать, какой поток закончился быстрее. Просто зная, что объединенный поток завершен.5. Мне все равно, какой из них закончился быстрее, я просто хочу знать, закончился ли из 3 потоков 1 из них, но с неизвестным количеством потоков
Ответ №1:
Ниже приведено простое решение для циклов с фиксированными потоками. Должно быть достаточно, если каждая задача имеет одинаковое время работы.
Воспринимайте каждую строку комментария как фрагмент кода.
int finished_tasks = 0;
int threads = 3;
int todo_tasks = 6;
int check_index = 0;
// ...
// Create thread by variable `threads` ...
for (int p = 0; p < threads; p )
pthread_create(amp;tid[p], NULL, dowork, full);
while( finished_tasks < todo_tasks ){
// Join one thread by check index;
// finished_tasks ;
// Check if finished tasks meets todo tasks, leave the while
// Immediately create a new thread to do jobs
// Move check index to next one.
}
Поскольку один поток завершен, и другой поток создается немедленно. Общее количество потоков фиксировано на threads
.
Профессиональный
- Простой
Con
- Запущенный поток отклоняется от 1 ~
threads
. Потому что цикл while всегда ожидает соединения с текущим потоком, в то время как другие потоки могут завершаться быстрее, чем текущий поток.
Это решение достаточно хорошо, если каждая задача имеет одинаковое время работы. Однако, если отклонение во времени работы слишком велико, вам необходимо выполнить синхронизацию для проверки, какой поток выполняется первым.