Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1

Процессы и потоки. Зависает в конце

04.01.2016, 14:46. Показов 1765. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Подскажите пожалуйста, что мне нужно добавить в код, чтобы нормально заканчивало выполнение. Кроме этого все работает отлично.

Выкладываю код.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//
//
//  Зависает в конце
 
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
    pid_t pid;
    char buf[]="Wellcome to Linux Embedded!-";
 
    pid=fork();
    if(pid==(pid_t)0){  // Child
        FILE *stream1;
        int count;
        char temp[80];
 
        sleep(1);
        printf("Start of Child\n");
        do{
            stream1=fopen("a.txt","r");
        }while(stream1==NULL);
        do{
            if( (fgets(temp,strlen(buf)+2,stream1))!=NULL){
                printf("%s",temp);
                memset(temp,0,sizeof(temp));
            }
        }while( (feof(stream1))==0 );
        fclose(stream1);
        printf("End of Child\n");
    }else{  // Parent
        FILE *stream;
        int count;
        char ch[2]={'\0','\0'};
        char temp[strlen(buf)];
 
        printf("Start of Parent\n");
        stream=fopen("a.txt","w");
        if(stream==NULL) printf("Open write error\n");
        for(count=1;count<=5;count++){
            strcpy(temp,buf);
            ch[0]=count+48;
            strcat(temp,ch);
            if( (fprintf(stream,"%s\n",temp))<0 ) printf("Write error\n");
        }
        fclose(stream);
        printf("End of Parent\n");
    }
    printf("End of main\n");
    return 0;
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.01.2016, 14:46
Ответы с готовыми решениями:

Потоки ввода/вывода, дочерние процессы и FIFO
Доброго времени суток! пишу курсовую, через неделю нужно здать, поэтому прошу помощи, знаю что эта тема уже раннее обсуждалась, но до...

Лаба на С. потоки и процессы
Здравствуйте! необходимо написать программу на С. вот задание: Разработать программу с графическим интерфейсом пользователя на...

Процессы и потоки в Qt
Наткнулся на такую статью в Хабре http://habrahabr.ru/post/150274/ Пишут, что создание потока через создание класса, наследуемого от...

12
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
04.01.2016, 15:03
Лучший ответ Сообщение было отмечено max_sk как решение

Решение

Перед окончание родительского процесса - wait(0);
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
05.01.2016, 15:08  [ТС]
Хорошо, спасибо...

Добавлено через 23 часа 56 минут
gng, может подскажете еще ? А какой wait() нужно выставить в этом коде, чтобы не зависало? Что то не могу разобраться в man'e...

Выкладываю код...

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//
// Зависает при выходе :-(
//
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define SHMSZ  20
#define NUM_PROC 10
 
int main()
{
    int shmid;
    key_t key;
    short *shm, *num, i, count;
    pid_t childpid;
 
    for(count=1;count<=NUM_PROC;count++){
        childpid=fork();
        if(childpid>=0){
            if(childpid==0){ // Child
                key=12345;
 
                if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
                    perror("Proc_func:Error of shmget");
                    exit(1);
                }
    
                if ((shm = shmat(shmid, NULL, 0)) == (short *) -1) {
                    perror("Proc_func:Error of shmat");
                    exit(1);
                }
 
                num=shm;
                if( count==1 ){
                    *num++=-2;
                    printf("Proc 1: -1");
                    for(i=1;i<=9;i++){
                        printf("%d",i);
                        *num++=i;
                    }
                    printf("\n");
                }else{
                    while(*num!=count*(-1));
                    printf("Proc %d: ",count);
                    for(i=1;i<=10;i++){
                        printf("%d",*num++);
                    }
                    printf("\n");
                    *shm=(count+1)*(-1);
                }
            }else{ // Parent
                while(*shm !=-10);
                if(count == 10){
                    if (shmdt(shm) == -1){
                        perror("Error of shmdt");
                        exit(1);
                    }
                    exit(0);
                }
            }
        }else{
            perror("Error of fork");
            exit(1);
        }
    }
 
    printf("End of main()\n");
}
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
05.01.2016, 15:35
Цитата Сообщение от max_sk Посмотреть сообщение
А какой wait() нужно выставить в этом коде, чтобы не зависало?
Здесь wait() недостаточно. Логика программы нарушена.
У вас на кажной итерации и родитель и все дочки вызывают fork(). В итоге получается 512 процессов.
Нужно в дочернем процессе дописать break для выхода из цикла.
В родительском wait (NULL) или waitpid (childpid, NULL, 0), что то же самое.
Если, конечно, в другом ошибок нет.
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
05.01.2016, 15:57  [ТС]
Спасибо, буду разбираться... :-?

Добавлено через 16 минут
Пытаюсь вспомнить теорию... fork () работает по принципу рекурсии? Тогда если я уберу цикл в начале, оставлю только первый fork () и добавлю еще один fork () внутри родителя, то у меня получится 4 процесса? Еще один форк внури следующего родителя то будет 6 процессов? И т.д.

Я правильно рассуждаю?
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
05.01.2016, 16:14
Цитата Сообщение от max_sk Посмотреть сообщение
Пытаюсь вспомнить теорию... fork () работает по принципу рекурсии?
Не уверен, что термин рекурсия здесь применим.
После форка оба процесса исполняются из той же точки. Различаются только возвращенными значениями fork();
Получается на первой итерации цикла (count=1) создается один процесс. Вместе с родителем их два.
На второй итерации каждый из них форкает ещё по процессу и т.д.
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
05.01.2016, 16:46  [ТС]
То есть, я правильно понимаю, что нижеследующий код создает 10 процессов? Или и тут есть зомби-орфаны, которых я не вижу?

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <unistd.h>
 
#define MAX_COUNT 5 // For 10 processes
 
void newchilds(int count);
 
int main()
{
    pid_t pid;
 
    newchilds(MAX_COUNT);
        
    return 0;
}
 
void newchilds(int count)
{
    pid_t pid;
 
    if(count>0){
        pid=fork();
        if(pid==0){ // Child
            printf("Child-%d PID=%d\n",count,(int)getpid());
        }else{ // Parent
            printf("Parent-%d PID=%d\n",count,(int)getpid());
            count--;
            newchilds(count);
        }
    }
}
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
05.01.2016, 19:40
Во первых, нужен wait() в теле Parent (напр перед 28 строкой). Во вторых, процессов здесь шесть - 1 родительский и 5 дочерних. Здесь, в отличие от предыдущего кода, 1) нет цикла 2) форк вызывает только первый (и единственный) родитель.
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
05.01.2016, 20:08  [ТС]
Но во второй итерации "рекурсии", тоже есть своя пара родитель-дочка, и в третьей тоже. Я прав?

Здесь как бы идет такая цепочка:
Code
1
2
3
4
5
6
7
                   Р
                 /    \
               Д      Р
                      /     \
                    Д        Р
                            /      \
                          Д        Р
, где Д - это дочка, а Р - родитель.

Добавлено через 52 секунды
Прошу прощения, не отобразилось...

Добавлено через 14 минут
Придется открывать учебник ...
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
05.01.2016, 20:40
Цитата Сообщение от max_sk Посмотреть сообщение
Но во второй итерации "рекурсии", тоже есть своя пара родитель-дочка, и в третьей тоже. Я прав?
Процесс, вызвав рекурсивную функцию, чудесным образом в другой процесс не превращается.
Также дочерний процесс, вызвав форк, другим процессом не становится, просто появляется ещё один.
Сколько раз вызван форк - столько и новых процессов.
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
05.01.2016, 20:46  [ТС]
Тогда почему в посте#3 получилось аж 512 процессов? Цикл же был рассчитан на 10 форков? :-?
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
05.01.2016, 20:58
Цитата Сообщение от max_sk Посмотреть сообщение
Тогда почему в посте#3 получилось аж 512 процессов? Цикл же был рассчитан на 10 форков? :-?
Потому что форки вызывались и родительскими, и дочерними процессами (с каждой итерацией цикла количество процессов удваивалось)
C
1
2
for (int i=0; i<10; i++) fork(); // 1024 процесса
for (int i=0; i<10; i++) if (!fork) break; //1+10 процессов.
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
05.01.2016, 21:04  [ТС]
Ладно, спасибо gng, попробую разобраться в этом...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.01.2016, 21:04
Помогаю со студенческими работами здесь

Процессы и потоки
Здравствуйте, КиберФорумчане!) Начал разбираться с процессами и потоками. Представление об этом небольшое, потому сразу хотелось бы...

Процессы и потоки
Здравствуйте. Помогите пожалуйста с задачей Нужно создать 2 приложения. Первое запускает второе приложение и проверяет, когда работа...

Процессы и потоки
Вопрос такой, как создать процесс, а потом добавить в этот процесс потоки?

потоки и процессы
Доброго времени суток! пишу прогу с использованием не стандартного протокола TCP, на который нет полного описания шифрования. ...

Потоки и процессы
Процесс А инициализирует массив случайными значениями и записывает их в файл, а затем запускает процесс Б в командной строке передается имя...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 30.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru