Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Пересылка символов по неименованному каналу. От родителя к двум потомкам. 
V
    Опции темы
Frostya
Дата 23.5.2009, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 9.5.2009
Где: Russia, Saint-Pet ersburg

Репутация: нет
Всего: нет



Доброго времени суток всем!

Передо мной стоит вот такая задачка:

Родительский процесс создаёт программный канал (неименованный) и затем ветвится дважды. Родительский процесс пишет в канал 10 символов. Если это сообщение для 1-го потомка, то ему (1-му) посылается сигнал SIGUSR1, если это сообщение для 2-го потомка, то 2-му посылается сигнал SIGUSR2. По получении сигнала, потомок читает из канала 10 символов и выводит на экран.
Родитель выбирает одного из потомков случайным образом, осуществляет запись и засыпает на 3 секунды, затем всё повторяется.

Вот что я накатал на данный момент:
Код

#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <wait.h>

static void sigu1() // обработчик сигнала 1
    {
        signal(SIGUSR1,sigu1);
        printf("SIGUSR1");
    }

static void sigu2() // обработчик сигнала 2
    {
        signal(SIGUSR2,sigu2);
        printf("SIGUSR2");
    }

int main()
{
    
pid_t childpid1; // PID потомка 1
pid_t childpid2; // PID потомка 2
int fd[2];
pipe(fd); // неименованный канал
int i=0;
char buf[10]={0,1,2,3,4,5,6,7,8,9}; // буфер для отсылки в канал

signal(SIGUSR1,sigu1);
signal(SIGUSR2,sigu2);

childpid1=fork();
if(childpid1==0)
    {
            // выполняется потомок 1
    }
if(childpid1>0)
    {
        childpid2=fork(); // потомок 2
        if(childpid2==0)
            {
                // выполняется потомок 2 
            }
        if(childpid2>0)
            {            
                for(i=0;i<10;i++)      // 10 записей в канал родительским процессом
                      {
                    if((rand()%2)==0) // посылаем сигнал SIGUSR1
                        {
                        kill(childpid1,SIGUSR1); 
                        }
                    else    // посылаем сигнал SIGUSR2
                        {
                        kill (childpid2,SIGUSR2); 
                        }                
                    sleep(3);
                    }
            }
    }    
exit(1);
}


Как читать из канала и записывать в него - я знаю.. Только вот не совсем понимаю, в какой конструкции в программе мне это писать (чтение из канала для каждого из потомков). В самих обработчиках сигналов или в местах выполнения дочерних процессов? Почему-то, когда я посылаю сигналы из родительского процесса, программа не входит в обработчики и ничего даже не печатает на экран.

Представленный выше код - это незавершенная программа. Так сказать, наброски (:
PM   Вверх
MAKCim
Дата 23.5.2009, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(Frostya @  23.5.2009,  00:47 Найти цитируемый пост)
Почему-то, когда я посылаю сигналы из родительского процесса, программа не входит в обработчики и ничего даже не печатает на экран.

может, потому что надо написать код, который будет выполняться в дочерних процессах?  smile 

Цитата(Frostya @  23.5.2009,  00:47 Найти цитируемый пост)
Только вот не совсем понимаю, в какой конструкции в программе мне это писать (чтение из канала для каждого из потомков)

я бы вообще не определял обработчики, а использовал sigwait

Код

sigset_t set;
siginfo_t info;

sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGUSR2);
sigprocmask(SIG_SETMASK, &set, NULL);

/* порождение процессов */
...
{
    /* дочерний процесс 1 */
    sigdelset(&set, SIGUSR2);
    while (sigtimedwait(&set, &info, NULL) < 0);
    /* чтение из пайпа */
}
...
{
    /* дочерний процесс 2 */
    sigdelset(&set, SIGUSR1);
    while (sigtimedwait(&set, &info, NULL) < 0);
    /* чтение из пайпа */
}



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Frostya
Дата 24.5.2009, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 9.5.2009
Где: Russia, Saint-Pet ersburg

Репутация: нет
Всего: нет



MAKCim, спасибо огромное! smile 

Подправил немного ваш код, добавил своего и программа готова!

Код

#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <wait.h>

static void sigchldu(int);

pid_t childpid1;
pid_t childpid2;

int main()
{

srand((unsigned int)time((time_t *)NULL));

sigset_t set;
siginfo_t info;
int er;

er=sigemptyset(&set);
if (er==-1) printf("sigemptyset() error");
er=sigaddset(&set, SIGUSR1);
if (er==-1) printf("sigaddset() SIGUSR1 error");
er=sigaddset(&set, SIGUSR2);
if (er==-1) printf("sigaddset() SIGUSR2 error");
er=sigprocmask(SIG_SETMASK, &set, NULL);
if (er==-1) printf("sigprocmask() error");

int fd[2];
er=pipe(fd);
if (er==-1) printf("pipe(fd) error");

char buf[10]="0123456789";
char bufch[10];

int i,n;

//signal(SIGUSR1,sigu1);
//signal(SIGUSR2,sigu2);
signal(SIGCHLD,sigchldu);

// порождение процессов
childpid1=fork();
if(childpid1==-1)
    {
        printf("fork-childpid1 error");
        exit(-1);
    }
    
if(childpid1==0) // потомок 1
    {
    close (fd[1]);
    while(1)
     {
     sigtimedwait(&set, &info, NULL);
     // чтение из пайпа
     n=read(fd[0],bufch,10);
     write(STDOUT_FILENO,bufch,n);
     printf(" - child 1\n");
     }
    }
if(childpid1>0)
    {    
        childpid2=fork(); 
        if(childpid2==-1)
            {
                printf("fork-childpid2 error");
                exit(-1);
            }
        if(childpid2==0)  // потомок 2
            {
            close (fd[1]);
            while (1)
                {
                sigtimedwait(&set, &info, NULL);
             // чтение из пайпа
             n=read(fd[0],bufch,10);
             write(STDOUT_FILENO,bufch,n);
                printf(" - child 2\n");
                }
            }
        if(childpid2>0)
            {    er=close (fd[0]);
                if (er==-1) printf("close(fd[0]) error");            
                for(i=0;i<10;i++)      // 10 записей в канал родительским процессом
                    {
                    er=write(fd[1],buf,10);                    
                    if(er==-1) printf("write in pipe error");
                    if((rand()%2)==0) // посылаем сигнал SIGUSR1
                        {
                        kill(childpid1,SIGUSR1);                    
                        }
                    else    // посылаем сигнал SIGUSR2
                        {
                        kill (childpid2,SIGUSR2); 
                        }
                    sleep(3);
                    }
            kill(childpid1,SIGKILL);
            kill(childpid2,SIGKILL);
            }
}
exit(1);
}

static void sigchldu(int signum)
    {
        signal(SIGCHLD,sigchldu);
        printf("CHLD DEAD\n");
    }


PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0592 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.