повторное использование переменной pthread_t для текущих запущенных потоков - PullRequest
8 голосов
/ 24 июня 2011

Я не уверен, что следующий код приведет к неопределенному поведению.

//global
pthread_t thread1;

void *worker(void *arg){
  //do stuff
}


void spawnThread(){
  //init stuff
  int iret1 = pthread_create( &thread1, NULL, worker, (void*) p);
}

Мой spawnThread создаст новый поток, используя глобальный поток 1.

Если я в данный моментЗапустив поток, который еще не завершен, я буду вызывать неопределенное поведение при запуске нового потока с использованием переменной thread1?

Если это проблема, имеет ли смысл сделать мою переменную pthread_t локальной для функции?Я думаю, что это может быть проблемой, потому что он будет использовать стек, и как только я вернусь из своей функции, которая будет удалена.

Если я сделаю свой pthread_t локальным для функции, я не смогу использовать pthread_joinв другой части моей программы.Является ли каноническое решение иметь счетчик с мьютексом, отслеживающий, сколько текущих потоков запущено?

спасибо

Ответы [ 3 ]

15 голосов
/ 24 июня 2011

pthread_t - это просто идентификатор. Вы можете скопировать его или уничтожить по желанию. Конечно, как вы упоминаете, если вы уничтожите его (потому что он локальный), вы не сможете использовать его для вызова pthread_join.

Если вы повторно используете одну и ту же переменную pthread_t для нескольких потоков, то, за исключением случаев, когда одновременно активен только один поток, вы перезаписываете старые значения новыми, и вы сможете вызывать pthread_join только для самая последняя начатая тема. Кроме того, если вы запускаете свои потоки из нескольких потоков, вам нужно защитить переменную pthread_t мьютексом.

Если вам нужно дождаться окончания потока, присвойте ему собственную переменную pthread_t и вызовите pthread_join в точке, где вам нужно ждать. Если вам не нужно ждать завершения потока, вызовите pthread_detach() после создания или используйте атрибуты создания, чтобы начать отсоединение потока.

2 голосов
/ 27 июня 2011

pthread_t - это просто идентификатор, и вы можете делать с ним все что угодно.Состояние потока поддерживается внутренне в библиотеке C (в случае Glibc / NPTL, на внутреннем struct thread в локальном хранилище потоков, доступ к которому осуществляется на x86 через регистр GS).

1 голос
/ 24 июня 2011

Проблема в том, что ваша переменная thread1 - единственный способ обратиться к вашей первой теме.

Решением, которое я часто использую, является наличие массива pthread_t, в котором хранятся идентификаторы потоков, на которые я должен ссылаться. В этом примере это статический массив, но вы также можете использовать динамически распределенную память.

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...