проблема создания нескольких потоков в C

#c #multithreading #pthreads

#c #многопоточность #pthreads

Вопрос:

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

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

void *thread_1(void *arg){
    printf("je suis le thread 1.n");
    (void) arg;
    pthread_exit(NULL);
    }
void *thread_2(void *arg){
    printf("je suis le thread 2.n");
    (void) arg;
    pthread_exit(NULL);
    }

void *thread_3(void *arg){
    printf("je suis le thread 3.n");
    (void) arg;
    pthread_exit(NULL);
    }

void *thread_4(void *arg){
    printf("je suis le thread 4 et je suis lance apres la fin du thread 1.n");
    (void) arg;
    pthread_exit(NULL);
    }

void *thread_5(void *arg){
    printf("je suis le thread 5  et je suis lance apres la fin du thread 1 et le thread 2.n");
    (void) arg;
    pthread_exit(NULL);
    }

void *thread_6(void *arg){
    printf("je suis le thread 6  et je suis lance apres la fin du thread 3 et le thread 5.n");
    (void) arg;
    pthread_exit(NULL);
    }

int main(void){
    pthread_t thread1;
    pthread_t thread2;
    pthread_t thread3;
    pthread_t thread4;
    pthread_t thread5;
    pthread_t thread6;
    pthread_create(amp;thread1, NULL, thread_1, NULL);
    pthread_create(amp;thread2, NULL, thread_2, NULL);
    pthread_create(amp;thread3, NULL, thread_3, NULL);
    if(pthread_join(thread1, NULL)){
        pthread_create(amp;thread4, NULL, thread_4, NULL);
        perror("pthread_join");
        return EXIT_FAILURE;
    }
    if(pthread_join(thread1, NULL) amp;amp; pthread_join(thread2, NULL)){
        pthread_create(amp;thread5, NULL, thread_5, NULL);
        perror("pthread_join");
        return EXIT_FAILURE;
    }
    if(pthread_join(thread3, NULL) amp;amp; pthread_join(thread5, NULL)){
        pthread_create(amp;thread6, NULL, thread_6, NULL);
        perror("pthread_join");
        return EXIT_FAILURE;
    }
    if(pthread_join(thread4, NULL) amp;amp; pthread_join(thread6, NULL)){
        printf("je suis l'etape 7 et la fin.n");
        perror("pthread_join");
        return EXIT_FAILURE;
    }
    else{
        return EXIT_FAILURE;
    }
    return 0;
}
  

когда этот код оправдан, я получаю это сообщение

 je suis le thread 2.
je suis le thread 1.
je suis le thread 3.
Segmentation fault (core dumped)
  

я хочу, чтобы потоки создавались так, чтобы они были похожи на среднее значение графика 1-2-3, затем 4 после окончания 1 и 5 после окончания 1 и 2, 6 будет создано после окончания 3 и 5, а последняя инструкция будет
выполнена после окончания 6 и 4, может кто-нибудь показать мнечто я сделал не так

Комментарии:

1. Я не понимаю логики. Существует большая вероятность, что thread5 это не инициализировано.

2. «В случае успеха функция pthread_join() должна возвращать ноль; в противном случае должен быть возвращен номер ошибки, указывающий на ошибку».

3. В Windows я получаю следующее: я использую le thread 1. я использую le thread 2. я использую le thread 3. я использую этап 7 и далее. pthread_join: ошибки нет

4. Второй вызов phread_join с использованием аргумента thread1 вызовет неопределенное поведение.

Ответ №1:

pthread_join возвращает 0, когда все в порядке. У вас есть логическая проблема в вашем коде, запуск следующих потоков только в случае сбоя и одновременный возврат с ошибками!

Проблема, с которой вы сталкиваетесь, заключается в том, что со всей этой неправильной логикой вы пытаетесь присоединиться к thread5 тому, что не инициализировано.

Попытайтесь исправить свой код, просто добавив пару else операторов и изменив проверенные значения на 0, теперь это имеет смысл:

 int main(void){
    pthread_t thread1;
    pthread_t thread2;
    pthread_t thread3;
    pthread_t thread4;
    pthread_t thread5;
    pthread_t thread6;
    if (pthread_create(amp;thread1, NULL, thread_1, NULL))
        {
           perror("pthread_create 1");
           return EXIT_FAILURE;
        }

   if (pthread_create(amp;thread2, NULL, thread_2, NULL))
        {
           perror("pthread_create 2");
           return EXIT_FAILURE;
        }
    if (pthread_create(amp;thread3, NULL, thread_3, NULL))
      {
         perror("pthread_create 3");
         return EXIT_FAILURE;
      }

    if(pthread_join(thread1, NULL)==0){
        if (pthread_create(amp;thread4, NULL, thread_4, NULL))
        {
           perror("pthread_create 4");
           return EXIT_FAILURE;
        }
    }
    else
    {
        perror("pthread_join");
        return EXIT_FAILURE;
    }
    if(pthread_join(thread2, NULL)==0){
        if (pthread_create(amp;thread5, NULL, thread_5, NULL))
        {
           perror("pthread_create 5");
           return EXIT_FAILURE;
        }


    }
    else
    {
        perror("pthread_join");
        return EXIT_FAILURE;
    }
    if(pthread_join(thread3, NULL)==0 amp;amp; pthread_join(thread5, NULL)==0){
        if (pthread_create(amp;thread6, NULL, thread_6, NULL))
        {
           perror("pthread_create 6");
           return EXIT_FAILURE;
        }
    }
    else
    {
        perror("pthread_join");
        return EXIT_FAILURE;
    }
    if(pthread_join(thread4, NULL)==0 amp;amp; pthread_join(thread6, NULL)==0){
        printf("je suis l'etape 7 et la fin.n");
    }
    else
    {
        perror("pthread_join");
        return EXIT_FAILURE;
    }

    return 0;
}
  

Комментарии:

1. Да, в основном, но вы не можете присоединиться к thread1 дважды, как это делает ваш код. Но как только основной поток присоединяется к thread1, ему все равно не нужно делать это снова.

2. Я увидел это в первый раз, но был ошеломлен ошибочной логикой. Спасибо (я на самом деле не проверял это)

3. спасибо, теперь код работает отлично, но я все еще не понимаю, почему вы говорите, что thread5 не инициализирован??

4. в вашем исходном коде, поскольку коды возврата были отменены, вы никогда не создавали thread5, но пытались присоединиться к нему, используя thread5 неинициализированную переменную for join , что объясняет сбой ( thread3 было нормально)

5. ах, еще раз спасибо, теперь я начинаю понимать логику этого