Выход основной нити, другой выход тоже?

У меня проблема с основным потоком и другим потоком в том же процессе. Когда основная функция возвращается, другой поток тоже выходит? Я немного смущаю меня. И я пишу некоторый тестовый код, например:

void* test1(void *arg)
{
    unsigned int i = 0;
    while (1){
        i+=1;
    }
    return NULL;
}

void* test2(void *arg)
{
    long double i = 1.0;
    while (1){
        i *= 1.1;
    }
    return NULL;
}

void startThread ( void * (*run)(void*), void *arg) {
  pthread_t t;
  pthread_attr_t attr;
  if (pthread_attr_init(&attr) != 0
      || pthread_create(&t, &attr, run, arg) != 0
      || pthread_attr_destroy(&attr) != 0
      || pthread_detach(t) != 0) {
    printf("Unable to launch a thread\n");
    exit(1);
  }
}

int main()
{
    startThread(test1, NULL);
    startThread(test2, NULL);

    sleep(4);
    printf("main thread return.\n");

    return 0;
}

Когда возвращается "основной поток". потушить, нить test1 и test2 также выйти, кто-нибудь может сказать мне, почему?

Ответы

Ответ 1

Когда основной поток возвращается, он завершает весь процесс. Это включает в себя все остальные потоки. То же самое происходит, когда вы вызываете exit.

Цель pthread_detach - сделать так, чтобы вам не нужно было присоединяться к другим потокам, чтобы освободить их ресурсы. Отсоединение потока не делает его существовавшим после завершения процесса, оно все равно будет уничтожено вместе со всеми другими потоками.

Ответ 2

Вы должны использовать pthread_join() для каждого из новых потоков, чтобы сообщить вызывающему потоку ждать подпотоков, приостановить выполнение - и завершить процесс - до тех пор, пока эти потоки не прекратятся.

Вызов pthread_detach в созданные потоки не будет поддерживать их после завершения процесса. Из linux справочная страница:

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

Иногда вы будете видеть pthread_exit в main вместо явных вызовов pthread_join, причем целью является выход из main таким образом позволит другим потокам продолжить работу. Фактически, страница linux man явно указывает это:

Чтобы разрешить другим потокам продолжить выполнение, основной поток должен завершиться вызовом pthread_exit(), а не exit (3).

Но я не знаю, будет ли это ожидаемым поведение на всех платформах, и я всегда придерживался использования pthread_join.

pthread_join требует pthread_t для целевого потока, поэтому ваш код нужно будет немного изменить, так как вам нужно создать оба потока перед вызовом pthread_join, чтобы подождать их обоих. Поэтому вы не можете позвонить в startThread. Вам нужно будет вернуть pthread_t или передать указатель на pthread_t на вашу функцию startThread.