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

С под Linux

Войти
Регистрация
Восстановить пароль
 
loorke
2 / 2 / 1
Регистрация: 03.12.2016
Сообщений: 10
Записей в блоге: 1
#1

Необычное поведение при использовании каналов из <unistd.h> - C Linux

12.12.2016, 04:18. Просмотров 345. Ответов 3

Нужно написать программу на Си использующую несколько процессов. При написании столкнулся с необычной проблемой. При вызове write(pipe[1], string, strlen(stirng) в стандартный вывод подаётся содержимое строки. Сама программа выглядит вот так:
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
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
 
 
int main(void) 
{
    int clientPipe[2];
    int* size = malloc(sizeof(int));
    char string[] = "Hello, world!\n";
 
 
    pid_t childpid;
    
    if ((childpid = fork()) == -1) {
        perror("fork");
        exit(1);
    } else if (childpid == 0) {
        /* Client */
 
        close(clientPipe[0]);
 
/*        scanf("%d", size);*/
/*        printf("%d\n", *size);*/
        /* write(clientPipe[1], size, sizeof(int)); */
        write(clientPipe[1], string, sizeof(string));
        printf("TROLOLO\n");
 
/*        time_t rawtime;*/
/*        srand(rawtime);*/
        exit(0);
    } else {
        /* Server */
    
        wait();
        close(clientPipe[1]);
        printf("Continue\n");
        *size = read(clientPipe[0], string, sizeof(string));
        printf("%s", string);
/*        read(clientPipe[0], size, sizeof(int));*/
/*        printf("%d\n", *size);*/
    }
       
    return(0);
}
Вывод при запуске следующий:
Код
TROLOLO
Hello, world!
Continue
Hello, world!
}
Почему Hello, world! выводится дважды?


И, в дополнение, когда нужно вызывать wait()? До закрытия канала и считывания или после?


Ну и раз уж зашла речь о wait(), почему при компиляции (clang source.c) я получаю следующий варнинг и как мне его не получать (гугл не помог):
Код
hello.c:37:9: warning: implicit declaration of function 'wait' is invalid in C99
      [-Wimplicit-function-declaration]
        wait();
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.12.2016, 04:18
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Необычное поведение при использовании каналов из <unistd.h> (C Linux):

Необычное поведение цикла for - C++ Builder
Label1-&gt;Caption = &quot;Âñåãî ïàðòèé: &quot; + IntToStr(VsegoPart); for(i=0; i&lt;VsegoPart;i++) { sum = sum + masiv; //ðàñ÷¸ò...

Необычное поведение порта - Администрирование Windows
Добрый день уважаемые форумчане. У меня к вам вопрос. Можно ли файерволл настроить так, что бы при опросе порта (например 80), его отклик...

Необычное поведение у цикла - PHP
Имеется следующий код: &lt;?php header(&quot;Content-type: text/html; charset=utf-8&quot;); require_once 'simple_html_dom.php'; $html =...

Необычное поведение оператора инкремента - C (СИ)
Добрый день! Это просто несчастье какое-то. Я пытаюсь посчитать коэффициенты корреляции, рассматривая строку из 16 массивов по 4 бит....

Необычное поведение &nbsp; - HTML, CSS
&amp;nbsp; отображается на сайте в виде мягкого знака, картинку прилагаю: del Дополнительная информация: в виде мягкого знака отображается в...

Распознавание речи и клавиатура - время ожидания - необычное поведение - Программирование Android
Столкнулся с необычной проблемой. Использую распознавание речи.. То есть при нажатии кнопки открывается окно диктования и после...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
shvyrevvg
465 / 444 / 166
Регистрация: 12.05.2016
Сообщений: 1,235
12.12.2016, 08:02 #2
Не вижу
C
1
pipe(clientPipe);
Что это за wait(), где он объявлен?
Цитата Сообщение от loorke Посмотреть сообщение
гугл не помог
man pipe
qwarta
73 / 73 / 7
Регистрация: 20.11.2009
Сообщений: 238
12.12.2016, 08:06 #3
Почему Hello, world! выводится дважды?
Нет открытия канала: pipe()
когда нужно вызывать wait()?
Кликните здесь для просмотра всего текста
Мы хотим, чтобы родительский процесс дождался завершения дочернего процесса и вывел сообщение о том, как был завершен дочерний процесс. Первую часть этой задачи мы могли бы решить с помощью уже известного нам механизма сигналов. Каждый раз, когда дочерний процесс приостанавливается или завершается, родительский процесс получает сигнал SIGCHLD. Мы могли бы приостановить работу программы до получения этого сигнала, но таким образом мы бы знали только то, что один из дочерних процессов программы завершился, но не знали бы, ни как он завершился, ни какой именно это был процесс. Причина этого конечно, в том, что сигналы сами по себе не несут никакой дополнительной информации. Однако, в нашем распоряжении есть функция wait(2), которая приостанавливает процесс до тех пор, пока один из его дочерних процессов не будет остановлен или не завершится, после чего возвращает информацию о том, какой процесс завершился и что стало причиной его завершения. Значение, возвращаемое функцией wait() – это PID завершившегося процесса, а аргументом функции должен быть указатель на переменную status типа int. В этой переменной функция вернет дополнительные сведения о том, как завершился процесс. Вы могли подумать, что после того как мы создали два процесса с помощью fork(), не так уж важно, запускаем ли мы новую программу в дочернем или в родительском процессе, ведь разница между ними невелика. Теперь вы знаете как минимум одну причину придерживаться строгих правил, ведь родительский процесс может следить за дочерним, в то время как обратное невозможно.

Значение переменной status, в которой функция wait() передает дополнительные данные о завершившемся процессе, представляет собой маску из нескольких разных параметров. В файле <sys/wait.h> определены макросы, упрощающие «расшифровку» этой маски. Макрос WIFEXITED возвращает значение 1, если процесс завершился «добровольно», то есть в результате вызова exit() или _exit(). В этом случае с помощью макроса WEXITSTATUS можно узнать код завершения, возвращенный процессом. Макрос WIFSIGNALED возвращает 1, если выполнение процесса было завершено сигналом. Номер этого сигнала можно узнать с помощью макроса WTERMSIG. Макрос WIFSTOPPED возвращает значение 1, если выполнение процесса было приостановлено сигналом, номер которого возвращает макрос WSTOPSIG.

почему при компиляции
C
1
#include <sys/wait.h>
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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
 
 
int main(void) 
{
    int clientPipe[2],status;
    int* size = malloc(sizeof(int));
    char string[] = "Hello, world!\n";
    pid_t childpid;
    
    pipe(clientPipe);
        if ((childpid = fork()) == -1) {
        perror("fork");
        exit(1);
    } else if (childpid == 0)                    /* Client */
            {
                close(clientPipe[0]);
                write(clientPipe[1], string, sizeof(string));
                close(clientPipe[1]);
                exit(0);
    } 
    else 
    {
        /* Server */
        
        close(clientPipe[1]);                        
        *size = read(clientPipe[0], string, sizeof(string));
        printf("%s", string);
        close(clientPipe[0]);
        if (wait(&status) == -1) 
            {
                perror("wait");
                return EXIT_FAILURE;
            }
        if (WIFEXITED(status))
            printf("Child terminated normally with exit code %i\n",WEXITSTATUS(status));
        if (WIFSIGNALED(status))
            printf("Child was terminated by a signal #%i\n", WTERMSIG(status));
        if (WCOREDUMP(status))
            printf("Child dumped core\n");
        if (WIFSTOPPED(status))
            printf("Child was stopped by a signal #%i\n", WSTOPSIG(status));
    }
    
       
    return(0);
}
drfaust
258 / 148 / 37
Регистрация: 02.10.2008
Сообщений: 538
Записей в блоге: 1
Завершенные тесты: 1
12.12.2016, 08:22 #4
Чёт не вижу где каналы создаются...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.12.2016, 08:22
Привет! Вот еще темы с ответами:

MFC/CinternetSession. Странное поведение при использовании прокси - Visual C++
Нужно было добавить в проект проверку валидности прокси серверов. Алгоритм работы простой: 1. Пытаюсь соединиться с конкретным сервером...

Странное поведение при использовании массива как параметра - C#
Всем привет. Есть след. метод: static void MixArray&lt;T&gt;(T arr) { Random rand = new...

Необычное поведение usb портов на материнской плате ecs p4m800-m7 - Материнские платы
материнка ecs p4m800-m7, не понятно работают usb порты, из всего домашнего оборудования определяют только PSP (Sony PlayStation Portable),...

Объяснить неожиданное поведение программы при использовании массивов и функции strcpy() - C++
Посмотрел в отладчике,получается,что конструктор берет переменную l,вместо k и записывает ее в sym ,почему? #include &lt;iostream&gt; ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
12.12.2016, 08:22
Ответ Создать тему
Опции темы

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