Когда я должен создать поток как отдельный, с самого начала?
Всякий раз, когда приложение не заботится о завершении этого потока и не заботится о возвращаемом им значении потока (поток может передать значение обратно другому потоку/приложению через pthread_exit
).
Например, в модели клиент-серверного приложения сервер может создавать новый поток для обработки каждого запроса. Но сам сервер не заботится о возвращаемом потоком значении потока. В этом случае имеет смысл создавать отдельные темы.
Единственное, что сервер должен гарантировать, это выполнение текущих обрабатываемых запросов. Что он может сделать, просто выйдя из основного потока, не выходя из всей программы/приложения. Когда последний поток в процессе завершается, приложение/программа естественным образом завершает работу.
Псевдокод может выглядеть так:
/* A server application */
void process(void *arg)
{
/* Detach self. */
pthread_detach(pthread_self());
/* process a client request. */
pthread_exit(NULL);
}
int main(void)
{
while (not_done) {
pthread_t t_id;
errno = pthread_create(&t_id, NULL, process, NULL);
if (errno) perror("pthread_create:");
}
/* There may be pending requests at this point. */
/* Just exit the main thread - not the whole program - so that remaining
requests that may still be processed can continue. */
pthread_exit(NULL);
}
Другим примером может быть поток демона или регистратора, который записывает некоторую информацию через равные промежутки времени, пока приложение работает.
Предлагает ли он какое-либо преимущество в производительности по сравнению с присоединяемым потоком?
С точки зрения производительности нет никакой разницы между потоками присоединяемыми и потоками отсоединенными. Единственное отличие состоит в том, что в случае отсоединенных потоков его ресурсы (такие как стек потоков и любая связанная память кучи и т. д. — именно то, что составляет эти ресурсы, зависит от реализации).
Законно ли не выполнять pthread_join() в присоединяемом (по умолчанию) потоке?
Да, можно не присоединяться к треду. pthread_join
- это просто удобная функция, которую ни в коем случае нельзя использовать, если вам это не нужно. Но обратите внимание, что созданные потоки являются присоединяемыми потоками по умолчанию.
Примером, когда вы можете захотеть присоединиться, является случай, когда потоки выполняют часть работы, которая разделена между ними. В этом случае вы захотите проверить все потоки, прежде чем продолжить. Хорошим примером является параллелизм фермы задач.
Или такой поток всегда должен использовать функцию detach() перед вызовом pthread_exit()?
Не обязательно. Но вы часто хотите решить, хотите ли вы присоединяемый или отдельный поток во время создания.
Обратите внимание, что хотя отсоединяемый поток можно создать, установив атрибут PTHREAD_CREATE_DETACHED
с вызовом pthread_attr_setdetachstate
, поток может принять решение об отсоединении в любой момент времени, например с pthread_detach(pthread_self())
. Кроме того, поток, имеющий идентификатор потока (pthread_t
) другого потока, может отсоединиться с помощью pthread_detach(thread_id);
.
person
P.P
schedule
18.07.2020