Форум программистов, компьютерный форум CyberForum.ru

Неименованные каналы POSIX - C Linux

Восстановить пароль Регистрация
 
maximq
0 / 0 / 0
Регистрация: 02.12.2015
Сообщений: 28
22.12.2016, 21:37     Неименованные каналы POSIX #1
Всем привет, делаю лабу по операционным системам. Не понимаю один момент.

Задание:
Родительский процесс создаёт два дочерних процесса. Далее он генерирует последовательность из n случайных целых чисел, выводит их на печать и передаёт обоим дочерним процессам. Первый дочерний процесс возвращает родительскому те из чисел, которые в своём десятичном представлении содержат цифру 3, а второй — цифру 5. Родительский процесс должен вывести полученные числа вместе с номерами дочерних процессов, от которых он эти числа получил.

Собственно проблема такая : Первому дочернему последовательность передаётся нормально, а вот второму нет, почему то зацикливается и там вообще левые числа.

Неполный код:

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
/*
 *
 *
 * Родительский процесс создаёт два дочерних процесса. 
 * Далее он генерирует последовательность из n случайных целых чисел, 
 * выводит их на печать и передаёт обоим дочерним процессам. 
 * Первый дочерний процесс возвращает родительскому те из чисел,
 * которые в своём десятичном представлении содержат цифру 3, а второй — цифру 5.
 * Родительский процесс должен вывести полученные числа вместе с номерами 
 * дочерних процессов, от которых он эти числа получил.
 *
 *
 */
 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
 
#include <unistd.h>
#include <sys/types.h>
 
#define N 10
#define ROUND 300
 
int main() {
    int cp_ds[2];
    int sec_cp_ds[2];
    pid_t cpid;
    pid_t sec_cpid;
    
    if (pipe(cp_ds) == -1){
        perror("Can't open pipe.");
        exit(EXIT_FAILURE);
    }
 
    cpid = fork();
    if (cpid == -1) {
        perror("Can't fork first children pipe.");
        exit(EXIT_FAILURE);
    }
 
    if (cpid > 0) {
        if (pipe(sec_cp_ds) == -1) {
            perror("Can't open pipe.");
            exit(EXIT_FAILURE);
        }
 
        sec_cpid = fork();
        if (sec_cpid == -1) {
            perror("Can't fork second children pipe.");
            exit(EXIT_FAILURE);
        }
 
        if (sec_cpid > 0) {
            // код родительского
            srand( time(NULL) );
            int * seq = (int *) calloc (N, sizeof(int));
            for ( size_t i = 0; i < N; ++ i ){
                seq[i] = rand() % ROUND;        
            }
 
            for ( size_t i = 0; i < N; ++ i) {
                printf("seq[ %lu ] = %3d\n" , i, seq[i]);
            }
 
            // передать обоим детям
            
            close(cp_ds[0]);
            write(cp_ds[1], (void *) seq, N * sizeof(int));
            close(cp_ds[1]);
 
            close(sec_cp_ds[0]);
            write(sec_cp_ds[1], (void *) seq, N * sizeof(int));
            close(sec_cp_ds[1]);
 
        } else {
            // код второго чилдрена
            int buf[N * sizeof(int)];
            int len;
            close(sec_cp_ds[1]);
            printf("Here2\n");
            
            while ((len = read(sec_cp_ds[0], buf, sizeof(int))) != 0){
                //printf("%d\n", *buf );
            }
        
            close(sec_cp_ds[0]);
        }
    } else {
        // а тут код чилдрена
        int buf[N * sizeof(int)];
        int len;
        close(cp_ds[1]);
        printf("Here1\n");
        while ((len = read(cp_ds[0], buf, sizeof(int))) != 0){
            printf("%d\n", *buf );
        }
    
        close(cp_ds[0]);
    }   
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.12.2016, 21:37     Неименованные каналы POSIX
Посмотрите здесь:

Каналы (PIPE) на Си. Небольшая недоработка с программой C Linux
C Linux Linux pipes(каналы)
Полудуплексные каналы C Linux
C Linux Обход каталога в POSIX
Интерпретация командной строки. Файловые операции POSIX. Прошу помочь дописать программу C Linux
C Linux Потоки Posix. C Linux
C Linux Точный delay() , желательно только POSIX
Posix поток C Linux
Очередь сообщений posix C Linux
C Linux Разделяемая память POSIX IPC как узнать, что память выделена и её уже можо использовать?
Изменить размер у POSIX shared memory сегмента C Linux
Генератор сигнала на C под POSIX C Linux

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
drfaust
251 / 141 / 36
Регистрация: 02.10.2008
Сообщений: 506
Записей в блоге: 1
Завершенные тесты: 1
23.12.2016, 13:59     Неименованные каналы POSIX #2
Может проблема в том, что pipe закрывается папашей сразу после записи. А вот кто из детей успеет добраться до pipe пока pipe не закрыт, тот и отрабатывает нормально
maximq
0 / 0 / 0
Регистрация: 02.12.2015
Сообщений: 28
23.12.2016, 17:16  [ТС]     Неименованные каналы POSIX #3
71 строка? без этого вроде вообще мусор будет передаваться

Добавлено через 2 часа 47 минут
Подправил, теперь всё ок.

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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
 *
 *
 * Родительский процесс создаёт два дочерних процесса. 
 * Далее он генерирует последовательность из n случайных целых чисел, 
 * выводит их на печать и передаёт обоим дочерним процессам. 
 * Первый дочерний процесс возвращает родительскому те из чисел,
 * которые в своём десятичном представлении содержат цифру 3, а второй — цифру 5.
 * Родительский процесс должен вывести полученные числа вместе с номерами 
 * дочерних процессов, от которых он эти числа получил.
 *
 *
 */
 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <sys/wait.h>
 
#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
 
#define ROUND 3000
 
bool includes_digit(int number, int digit){
    while (number != 0){
        int cur_dig = number % 10;
        if (digit == cur_dig){
            return true;
        }
 
        number = (number / 10);
    }
}
 
int main(int argc, char * argv[]) {
    int cp_ds[2];
    int sec_cp_ds[2];
    int back_p[2];
    int sec_back_p[2];
    pid_t cpid;
    pid_t sec_cpid;
    
    if (argv[1] == NULL){
        perror("Enter the N please.");
        exit(EXIT_FAILURE);
    }
 
    int N = atoi(argv[1]);
 
    if (pipe(cp_ds) == -1){
        perror("Can't open pipe.");
        exit(EXIT_FAILURE);
    }
 
    if (pipe(back_p) == -1){
        perror("Can't open pipe.");
        exit(EXIT_FAILURE);
    }
 
    if (pipe(sec_back_p) == -1){
        perror("Can't open pipe.");
        exit(EXIT_FAILURE);
    }
    
    cpid = fork();
    if (cpid == -1) {
        perror("Can't fork first child pipe.");
        exit(EXIT_FAILURE);
    }
 
    if (cpid > 0) {
        if (pipe(sec_cp_ds) == -1) {
            perror("Can't open pipe.");
            exit(EXIT_FAILURE);
        }
 
        sec_cpid = fork();
        if (sec_cpid == -1) {
            perror("Can't fork second child pipe.");
            exit(EXIT_FAILURE);
        }
 
        if (sec_cpid > 0) {
            // Parent
            // Generate random sequence
            srand( time(NULL) );
            int * seq = (int *) calloc (N, sizeof(int));
            for ( size_t i = 0; i < N; ++ i ){
                seq[i] = rand() % ROUND;        
            }
 
            for ( size_t i = 0; i < N; ++ i) {
                printf("seq[%lu]  =  %4d\n" , i, seq[i]);
            }
            printf("\n");
 
            // Give both child
            close(cp_ds[0]);
            write(cp_ds[1], (void *) seq, N * sizeof(int));
            close(cp_ds[1]);
 
            close(sec_cp_ds[0]);
            write(sec_cp_ds[1], (void *) seq, N * sizeof(int));
            close(sec_cp_ds[1]);
 
            // Get back from childs
            int buf;
            ssize_t len;
 
            // From first child
            close(back_p[1]);
            len = read(back_p[0], &buf, sizeof(int));
            int size = buf;
            for (int i = 0; i < size; ++ i){
                len = read(back_p[0], &buf, sizeof(int));
                int cur = buf;
                printf("Get from first child = %d\n", cur);
            }
            printf("\n");
            close(back_p[0]);
 
 
 
            // From second child
            len = read(sec_back_p[0], &buf, sizeof(int));
            int size2 = buf;
            for (int i = 0; i < size2; ++ i){
                len = read(sec_back_p[0], &buf, sizeof(int));
                int cur = buf;
                printf("Get from second child = %d\n", cur);
            }
            close(back_p[0]);
 
 
        } else {
            // Second child
            int buf[N * sizeof(int)];
            ssize_t num;
            int * seq = (int *) calloc (N, sizeof(int));
            int ind = 0;
 
            // Read from parent
            close(sec_cp_ds[1]);
            num = read(sec_cp_ds[0], buf, N * sizeof(int));
            for (int i = 0; i < N; ++ i){
                if (includes_digit(buf[i], 5)){
                    seq[ind] = buf[i];
                    ind++;
                }
            }
            close(sec_cp_ds[0]);            
            
            // Write to parent  
            close(sec_back_p[0]);
            write(sec_back_p[1], &ind, sizeof(int));
            for (int i = 0; i < ind; ++ i){
                write(sec_back_p[1], &seq[i], sizeof(int));
            }
            close(sec_back_p[1]);       
        }       
    } else {
        // Child
        int buf[N * sizeof(int)];
        ssize_t num;
 
        int * seq = (int *) calloc (N, sizeof(int));
        int ind = 0;
        
        // Read from parent
        close(cp_ds[1]);
        num = read(cp_ds[0], buf, N * sizeof(int));
        for (int i = 0; i < N; ++ i){
            if (includes_digit(buf[i], 3)){
                seq[ind] = buf[i];
                ind++;
            }
        }
        close(cp_ds[0]);
        
        // Write to parent
        close(back_p[0]);
        write(back_p[1], &ind, sizeof(int));
        for (int i = 0; i < ind; ++ i){
            write(back_p[1], &seq[i], sizeof(int));
        }
        close(back_p[1]);
    
    }
    return 0;
}
Yandex
Объявления
23.12.2016, 17:16     Неименованные каналы POSIX
Ответ Создать тему
Опции темы

Текущее время: 23:39. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru