#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
неинициализированную переменную forjoin
, что объясняет сбой (thread3
было нормально)5. ах, еще раз спасибо, теперь я начинаю понимать логику этого