повторное использование переменной pthread t для текущих потоков
Я не уверен, приведет ли следующий код к неопределенному поведению.
//global
pthread_t thread1;
void *worker(void *arg){
//do stuff
}
void spawnThread(){
//init stuff
int iret1 = pthread_create( &thread1, NULL, worker, (void*) p);
}
My spawnThread создаст новый поток, используя глобальный thread1.
Если я в настоящее время запускаю поток, который не завершен, я каким-то образом вызову неопределенное поведение при запуске нового потока с помощью переменной thread1?
Если это проблема, имеет ли смысл сделать мою переменную pthread_t локальной для функции? Я думаю, что это может быть проблемой, потому что это будет использовать стек, и как только я вернусь из своей функции, которая будет удалена.
Если я сделаю pthread_t локальным для функции, я не могу использовать pthread_join в другой части моей программы. Является ли каноническим решением иметь счетчик мьютекса, отслеживающий количество текущих потоков?
спасибо
3 ответов
The pthread_t
- Это просто идентификатор. Вы можете скопировать его или уничтожить по желанию. Конечно, как вы упомянули, если вы уничтожите его (потому что он локальный), то вы не можете использовать его для вызова pthread_join
.
если вы повторно используете то же самое pthread_t
переменная для нескольких потоков, если только не существует только одного активного потока в то время, когда вы перезаписываете старые значения новыми, и вы сможете вызвать только pthread_join
в последнем запущенном потоке. Кроме того, если вы начинаете свой потоки изнутри нескольких потоков, то вам нужно будет защитить pthread_t
переменная с мьютексом.
Если вам нужно дождаться завершения вашей нити, дайте ей свою собственную pthread_t
переменной и вызов pthread_join
в точке, где вам нужно подождать. Если вам не нужно ждать завершения вашего потока, позвоните pthread_detach()
после создания или используйте атрибуты создания для запуска отсоединенного потока.
проблема, ваша thread1 переменная-единственный способ обратиться к вашему первому потоку.
решение, которое я часто использую, имеет массив pthread_t, где хранить идентификаторы потоков, на которые мне нужно ссылаться. В данном примере это статический массив, но вы можете также использовать динамически alloced памяти.
static pthread_t running_threads[MAX_THREAD_RUNNING_LIMIT];
static unsigned int running_thread_count = 0;
// each time you create a new thread:
pthread_create( &running_threads[running_thread_count], blabla...);
running_thread_count++;
// don't forget to check running_thread_count against the size
// of your running thread size MAX_THREAD_RUNNING_LIMIT
когда вам нужно присоединиться () к ним, просто сделайте это в цикле:
for(i =0; i<running_thread_count; i++)
{
pthread_join(&running_threads[i], &return_value);
}
pthread_t
- Это просто идентификатор, и вы можете делать все что угодно с ним. Состояние потока поддерживается внутренне в библиотеке C (в случае Glibc / NPTL, на внутреннем struct thread
на локальном хранилище потоков, доступ к x86 через GS
Регистрация).