Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 19.12.2013
Сообщений: 5

Fork() вместо getpid

25.12.2014, 19:14. Показов 1719. Ответов 1
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задание из инста: Разработайте на языке «С» программу создающую заданное в параметрах количество процессов, посылки сигнала SIGALRM всем процессам порожденным задачей и получения от каждого из них отклика SININT. Если за 10 секунд ожидания ответные сигналы не получены, то программа посылает SIGKILL всем своим потомкам, дожидается их завершения и при благополучном исходе формирует нулевой код возврата. Если хоть один процесс-потомок завершился с кодом возврата отличным от нуля, то должен быть сформирован код возврата с максимальным значением полученным от процессов-потомков.
Вот код
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
int answers;
void signalReceiverInt(int sig)
{
    //printf("получен SIGINT\n");
    signal(sig ,&signalReceiverInt);
    answers++;
}
 
void signalReceiverAlrm(int sig)
{
    signal(sig ,&signalReceiverAlrm);
        kill(getppid(), SIGINT);
        //printf("Сингал SIGALR для PID=%i, родитель PPID=%i\n", getpid(), getppid());
}
 
int main(int argc, char *argv[]){
    
    answers=0;
    int count=atoi(argv[1]);
    int prc[count];
    signal(SIGINT   ,&signalReceiverInt);
    signal(SIGALRM   ,&signalReceiverAlrm);
    
    int mainPid=getpid();
    printf("mainPid: %d\n",mainPid);
    int i;
    for (i=0; i<count; i++)
        if(mainPid==getpid())
            prc[i]=fork();
    
    if(mainPid==getpid())
    {
 
        sleep(1);
        for (i = 0; i < count; i++){
            kill(prc[i], SIGALRM);
            sleep(10);
        }
        
        if(count!=answers){
            exit(0); 
        }else{
 
            //Убиваем процессы,если откликнулись не все
            for (i = 0; i < count; i++) 
                kill(prc[i], SIGKILL);
            int maxCode=0;
            int ecode=0;
 
            for (i = 0; i < count; i++)
            {
                waitpid(prc[i], &ecode, NULL);
                if(ecode > maxCode)
                    maxCode=ecode;
            }
            exit(maxCode);
        }
    } else {
    //printf("NUM: %d\n",x);
    //printf("NUM: %d\n",y);
    while(1)
    {
        sleep(1);
    }
}
 
       exit(0);
Но препод попросил не использовать getpid, где это возможно, а использовать коды возврата fork
Который 0 в дочернем и pid дочернего в родительском
Но я не догоняю как это сделать. Подкинете пару идей?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
25.12.2014, 19:14
Ответы с готовыми решениями:

Fork() процессы
Здравствуйте, Помогите please объяснить программу, что она выполняет (Linux) main() { int n; for (n=0;n&lt;10;n++) ...

Fork() возвращает -1
Есть модуль, которая слущает UDP порт на наличие данных, когда приходят данные, вызывается функция fork,родительский процесс возвращается...

Fork,waitpid
Имеется программа написанная на Си,которая выполняет рекурсивный поиск файлов в каталогах и добавляет к началу имени файла его порядковый...

1
 Аватар для chocobo
16 / 16 / 17
Регистрация: 22.06.2013
Сообщений: 73
Записей в блоге: 3
26.12.2014, 06:19
Здравствуйте! Меня тут недавно попросили прокомментировать код. Я его выкладываю здесь, почитайте, и возможно это Вам поможет.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
int pid; // переменная которая содержит PID (идентификатор процесса, просто его опознавательный номер)
pid = fork(); // создаем дочерний процесс.
// тут очень важный момент, в РОДИТЕЛИ, переменная pid будет содержать ИДЕНТИФИКАТОР ДОЧЕРНЕГО ПРОЦЕССА, который не равен нулю
// у ПОТОМКА, переменная pid будет равна НУЛЮ
// То есть если написать так (как в вашей программе)
if (p1 = fork())
 {
   // КОД КОТОРЫЙ БУДЕТ ВЫПОЛНЯТЬ РОДИТЕЛЬ
 }
else
{
 // КОД, КОТОРЫЙ ВЫПОЛНИТ ДОЧЕРНИЙ ПРОЦЕСС, ПОТОМУ ЧТО p1 = 0 у потомка!
}
ТЕперь сам код, который меня попросили прокомментить
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
 
int fact(int a);
 
int main(int argv, char *args[])
{
    int n = atoi(args[1]);
    int k = atoi(args[2]);
    int p1,p2,p3;
    int *st;
       
        /*
         * Возвращаемые значения fork() очень интересны.
         * Одно из них - 0, другое – ненулевое значение (PID - ID процесса).
         * Процесс, который получает 0, называется ПОРОЖДЕННЫМ процессом,
         * а ненулевое значение (PID - ID процесса) достается исходному процессу, который является родительским процессом.
         * Возвращаемые значения используют, для того чтобы определить, где какой процесс.
         */
    if(p1=fork())
    {
                /* Этот блок кода (три нижних if'а) предназначен для родительского процесса
                 * Потому что fork() возвращает идентификатор процесса (PID) родителю,
                 * а потомку возвращается 0 !!!
                 * По этой причине, код в третьем else, предназначен для первого потомка !!!
                 * Назовем этого родителя Алиса :)
                 */
 
                /* На данном этапе, Алиса породила дочь Алиса_1  
                 * УЖЕ породила
                 */
 
                /*
                 * Теперь идет порождение второго потомка Алисы, то есть Алисы_2
                 */
        if(p2=fork())
        {
                        /*
                         * На данном этапе Алиса породила дочь Алиса_2
                         */
 
                        /*
                     * Теперь идет порождение третьего потомка Алисы, то есть Алисы_3
                     */
            if(p3=fork())
            {
                                /* Код ниже предназначен для Алисы!!! ДЛЯ ИЗНАЧАЛЬНОГО РОДИТЕЛЯ, КАК И ВСЕ В if'ах!!!*/
 
                                /* на данном этапе Алиса породила дочь Алиса_3 */
 
                                /*
                                 * Дочерние процессы созданы.
                                 * Чтобы родители ожидали завершения дочернего процесса
                                 * необходимо сделать это явно, то есть вызвав функции waitpid()
                                 * Даже по названию видно предназначение
                                 * wait - ждать, pid = process ID, то есть идентификатор процесса
                                 * в данном случае, p1,p2,p3 - это ID Алисы_1,Алисы_2,Алисы_3!!!
                                 */
 
                                /* Алиса (родитель) ждет пока потомки Алиса_1,Алиса_2,Алиса_3
                                 * выполнят свою работу, тоесть код в else'ах!
                                 */
                waitpid(p1,st,0);
                waitpid(p2,st,0);
                                waitpid(p3,st,0);
                /*
                                 * То есть теперь программа замерла и ждёт
                                 * Когда выполнится код в else !!!
                                 * Во всех трех else!!!
                                 * Теперь стоит прочесть, что происходит в else'ах
                                 */
 
                                /*
                                 * После того как код в else'ах выполнился
                                 * мы открываем файлы на чтение
                                 */
                FILE * nkff = fopen("nkf.txt","r");
                FILE * kff = fopen("kf.txt","r");
                FILE * nff = fopen("nf.txt","r");
                   
                int nkf, kf, nf;
                /* считываем из файлов значения факторилов и записываем их в переменные nkf,kf,kff */                        
                fscanf(nkff, "%d",&nkf);
                fscanf(nff, "%d", &nf);
                fscanf(kff, "%d", &kf);
                /* выводим в консоль значения этих переменных */    
                printf("%d nkf\n", nkf);
                printf("%d nf\n", nf);
                printf("%d kf\n", kf);
                /* удаляем созданные файлы*/    
                unlink("nkf.txt");
                unlink("nf.txt");
                unlink("kf.txt");
                /*производим какие-то вычисления*/    
                double ret = nf/(kf*nkf);
                                /* выводим конечный результат */
                printf("%f\n", ret);
                   
                return 0;
                               
            }
                 /*
                  * Код внутри трех нижних else'ов
                  * Предназначен для потомков
                  */
            else
            {
                                /*
                                 * Этот блок кода предназначен для Алисы_3!!!
                                 */
                                /* n и k - это два передаваемых нашей программе параметра */
                                /* в функцию fact() передаем их разность */
                                /* теперь стоит прочесть комменты к этой функции, чтоб понять как она работает ^:) */
                int nkf = fact(n-k);
                                /* в переменной nkf у нас лежит факториал числа*/
 
                                /* Открываем файл */
                FILE * nkff = fopen("nkf.txt","w");
                                /* Записываем значение факториала числа в файл */
                fprintf(nkff, "%d", nkf);
                                /* Закрываем файл, чтобы освободить дескриптор*/
                fclose(nkff);
            }
        }
        else
        {
                                /*
                                 * Этот блок кода предназначен для второго потомка, Алисы_2!!!
                                 */
                                /*Все аналогично первому else */
            int kf = fact(k);
            FILE * kff = fopen("kf.txt","w");
            fprintf(kff, "%d", kf);
            fclose(kff);
        }
    }
    else
    {
                /*
                 * Этот блок кода предназначен для первого потомка Алиса_1!!!
                 * Почему?
                 * Потому что p1=fork() - возвращает 0 потомку и PID родителю!
                 */
                        /*Все аналогично первому else */
        int nf = fact(n);
        FILE * nff = fopen("nf.txt","w");
        fprintf(nff, "%d", nf);
        fclose(nff);
    }
   
    return 0;  
}
 
int fact(int a)
{
    int sum = 1;
        /* Если первый передаваемый параметр больше второго, то их разность будет отрицательна
         * Поэтому мы умножаем на -1, чтобы было положительное значение
         * То есть по сути не важно, какой параметр передавать первым, а какой вторым
         */
    if(a<0)
        a*=-1;
    /* вычисляем факторил разности параметров, то есть тупо перемножаем все предыдущие числа до него, с шагом один*/
    for(int i=1;i<=a;i++)
        sum*=i;
    /* ну и возвращаем результат. Почему переменная называется sum, хотя это не сумма - не знаю :) */    
    return sum;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.12.2014, 06:19
Помогаю со студенческими работами здесь

Popen не вызывает fork
Столкнулся с проблемой.В программе с помощью popen вызываю другую программу в качестве дочернего процесса.Все работает,но в терминале я...

Нюансы работы fork()
Всем привет. Вопрос такой. Есть программа, которая записывает себе в статические переменные важные данные. Запись процесс...

Переделать задачу с потоками на fork
Нужно скопировать файл, использую параллельное программирование. Есть реализация этой задачи с использованием потоков(pthread), нужно...

Особенности использования fork и exec
Подскажите пожалуйста, если мы используем в программе вызов fork, а потом exec, или просто сразу exec, то наша программа (процесс)...

Fork не создал дочерний процесс
Доброго дня! Зашел в тупик, переписываю кусок кода... pid_t wpid=0; wpid=fork(); switch(wpid) { case(-1): {


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

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru