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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> процесс, потомки, сигналы 
:(
    Опции темы
rthsobakas
Дата 29.9.2008, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 562
Регистрация: 20.9.2007

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





Задача следюущая: 
Процесс 1 открывает фаил и порождает потомков 2 и 3 , процесс 1 с интервалом в 1 сек (через alarm) по очереди посылает N сигналов sig1 процессам 2 и 3 которые по каждому сигналу пишут в общий фаил по M чисел. Потом процесс 1 посылает потомкам сигнал sig2, процесы завершаются. Процесс 1 считывает данные из фаила и выводит на экран.

Как посылается сигнал потомкам? 
Типо потомок так создается:
int pid2;
pid2=fork();
if (pid2==0){
}
Зачем тут условие? и Что оно озночает(Почему именно с нулем сравнивает)? 
Что такое Alarm и как через него послать сигнал?



И ещё скажите что означают следующие записи?
 1)  struct sigaction action;
 2)  action.sa_handler = &parent_handler;
PM   Вверх
MAKCim
Дата 29.9.2008, 21:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



rthsobakas, 
прочитайте сначала какую-нибудь литературу
а лучше
man 2 fork
man 2 sigaction
man 2 alarm
man 2 kill

Это сообщение отредактировал(а) MAKCim - 29.9.2008, 21:08


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

PM MAIL   Вверх
rthsobakas
Дата 29.9.2008, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 562
Регистрация: 20.9.2007

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



ну прочитал. 
fork -порождает процесс
Например 1 процесс породил 2 процесс. При успешном завершении родителю возвращается PID процесса-потомка, а процессу-потомку возвращается 0. Типо условие нужно для проверки создался он или нет, иначе можно без условия сделать ,но прога работать наверно работать не будет.
Код

int main(){
pid_t pid2;
pid2=fork();
if (pid2==0){
}}



sigaction int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
Системный вызов sigaction используется для изменения действий процесса при получении соответствующего сигнала. 

alarm это типо слипа, задержка вообщем,

 kill завершить процесс. kill посылает указанный сигнал указанному процессу. Если не указано ни одного сигнала, посылается сигнал TERM. Сигнал TERM завершит те процессы, которые не обрабатывают его приход. Для других процессов может быть необходимым послать сигнал 9, поскольку этот сигнал перехватить нельзя.
Типо он используется для передачи сигнала потомку,тока не понятно как,,,



Ну я прогу начал писать,но в фаил она не забивает символы почему то... Вернее не почему то а потому что я хз как правильно сигнал отправить.
Код

#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>

FILE *fp;

void hadler(nsig){
char c;
int i,m=5;
for (i=0;i<m;i++){
c=random(100);
putc(c,fp);
}
}

void vi(void){
int st;
wait(&st);
}

void main(void){
int pid2,pid3,n=10,i;
char c;
fp=fopen("test.txt","w+");

printf("Starting process 1, pid=%d\n",getpid());

//2 потомок создали
pid2=fork();
if (pid2==0)
{
printf("Starting process 2,pid=%d\n",getpid());
for (i=0;i<n;i++){
//отправили сигнал для  ввода символов
alarm(1);
signal(SIGALRM,hadler);
}
//сигнал для завершения
signal(SIGINT,vi);
}


pid3=fork();
if (pid3==0)
{
printf("Starting process 3,pid=%d\n",getpid());
for (i=0;i<n;i++){
alarm(1);
signal(SIGALRM,hadler);
}
signal(SIGINT,vi);
}

while (!feof(fp)){
c=getc(fp);
printf("%c",c);
}

signal(SIGINT,vi);
printf("Process 1 ended\n");
fclose(fp);
exit(0);
}

PM   Вверх
lamao
Дата 29.9.2008, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 23.4.2008

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



Вообще-то судя по постановке задачи необходимости в порождениях процессов нет. Здесь целесообразно использовать потоки как минимум по трем причинам:
1) Создание потока на порядок дешевле чем создание процесса
2) Так как первоначальный процесс контролирует выполнение дочерных процессов и имеет место межпроцесное взаимодействие.
3) Запрограммировать все это будет проще и читабельнее именно с использовнием потоков.

В общем я бы в рамках одного родительского процесса создавал бы все эти сервисные потоки.
Детальнее нужно читать в 
Код

man pthread


PM MAIL WWW   Вверх
MAKCim
Дата 30.9.2008, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Код

#define N 10
#define M 20

static sigset_t set;

static int fd;

static void handle()
{
    int i;
    char buffer[32];
    for (i = 0; i < M; ++i) {
        sprintf(buffer, "%u\n", i);
        flock(fd, LOCK_EX);
        write(fd, buffer, strlen(buffer));
        flock(fd, LOCK_UN);
    }
}

static void child_routine()
{
    int number, flags, count, ready;
    struct timespec timespec = {
        .tv_sec = 0,
        .tv_nsec = 0
    };    
    flags = 0;
    count = 0;
    ready = 0;
    for (;;) {
        switch (sigtimedwait(&set, NULL, &timespec)) {
            default:
                break;
            case SIGUSR1:
                ++count;
                break;
            case SIGUSR2:
                flags = 1;
        }
        for (; ready < count; ++ready) handle();
        if (count == M && flags) break;
    }
}

static void read_file()
{
    int i;
    lseek(fd, 0, SEEK_SET);
    FILE *f = fdopen(fd, "r+");
    while (fscanf(f, "%u", &i) != EOF) printf("%u\n", i);
    close(fd);
}

int main()
{
    pid_t pids[2];
    sigset_t __set;
    int i;
    if ((fd = open("data", O_CREAT | O_RDWR | O_EXCL)) < 0) {
        perror("open");
        return -1;
    }
    sigaddset(&set, SIGUSR1);
    sigaddset(&set, SIGUSR2);
    sigprocmask(SIG_BLOCK, &set, NULL);
    for (i = 0; i < 2; ++i) {
        if ((pids[i] = fork()) == 0) {
            child_routine();
            _exit(0);
        } else if (pids[i] < 0) {
            perror("fork");
            for (--i; i >= 0; --i) kill(pids[i], SIGKILL); // destroy created processes
            return -1;
        }
    }
    sigemptyset(&__set);
    sigaddset(&__set, SIGALRM);
    for (i = 0; i < 2; ++i) {
        int count = N, sig;
        for (; count; --count) {
            alarm(1);
            sigwait(&__set, &sig)
            kill(pids[i], SIGUSR1);
        }
    }
    for (i = 0; i < 2; ++i) kill(pids[i], SIGUSR2);
    for (i = 0; i < 2; ++i) waitpid(pids[i], NULL, 0);
    read_file();
    return 0;
}


Это сообщение отредактировал(а) MAKCim - 30.9.2008, 12:46


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

PM MAIL   Вверх
rthsobakas
Дата 30.9.2008, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 562
Регистрация: 20.9.2007

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



ммм... так то спасибо конечно, но хотелось бы разобраться самому( к тому же код компилится с ошибками)

Может есть специальные книги, авторы какие нибудь которые на примерах показывают? Просто рылся в яндексе,гугле там в основном статьи небольшие, причем проги  простые(процесс породил потомка и  убил его)... Или наоборот навароченные
PM   Вверх
rthsobakas
Дата 30.9.2008, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 562
Регистрация: 20.9.2007

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



Вообщем я вроде понял как сигнал процессу передать

Код


#include <stdio.h>
#include <signal.h>

FILE *fil;
int count=0;

void catcher1()
{
int i;
fil=fopen("test.txt","a");
count++;
printf("Сигнал%d:",count);fprintf(fil,"Сигнал%d:",count);
for (i=0;i<M;i++){printf("%d",count);fprintf(fil,"%d",count);}
printf("\n");fprintf(fil,"\n");
fclose(fil);
}



int main(){
pid_t pid2,pid3;
int st,j;
fil=fopen("test.txt","w+");
fclose(fil);
printf(" начало...\n");
pid2=fork();
if (pid2==0){
signal(SIGUSR1,catcher1);
}


pid3=fork();
if (pid3==0){
signal(SIGUSR1,catcher1);
}


kill(pid2,SIGUSR1);
kill(pid3,SIGUSR1);

printf(" Программа закончена...");
return 0;
}



kill(pid2,SIGUSR1);
kill(pid3,SIGUSR1);  
ими сигнал типо передается 2 и 3 потомку, а signal(SIGUSR1,catcher1); типо в потомке ловится.Тока результат разный получается почему то хз почему....((((

user@user:~/Desktop> lab4
 начало...
Сигнал1:1111111111
 Программа закончена...Определяемый пользователем сигнал 1
user@user:~/Desktop> Сигнал1:1111111111
Сигнал2:2222222222
Сигнал3:3333333333
 Программа закончена...Сигнал1:1111111111
Сигнал2:2222222222
 Программа закончена...   

Вот это не понятно почему появляется, когда прога заработала
Определяемый пользователем сигнал 1
user@user:~/Desktop> 


Почему 3 вызов кэтчера происходит тоже не ясно Сигнал3:3333333333

И почему повотрно прога выполняется ?
 Программа закончена...Сигнал1:1111111111
Сигнал2:2222222222
 Программа закончена...  


Вообщем кто как думает в чем касяк?Я думал проблема в том что процесс потомок не завершается и выполняется рандомом  ещё несколько раз и использовал типо Wait(&st) (написано в литературе что он для завершения процесса типо), но он вроде как ваще не влияет на исход результата...

По логике должен получатся результат:

user@user:~/Desktop> lab4
 начало...
Сигнал1:1111111111
Сигнал2:2222222222
 Программа закончена...

Потом если это в цикле сделать например 2 раза(kill(pid2,SIGUSR1);kill(pid3,SIGUSR1);  )

То  получится должно
user@user:~/Desktop> lab4
 начало...
Сигнал1:1111111111
Сигнал2:2222222222
Сигнал3:3333333333
Сигнал4:4444444444
 Программа закончена...



Это сообщение отредактировал(а) rthsobakas - 30.9.2008, 12:39
PM   Вверх
MAKCim
Дата 30.9.2008, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(rthsobakas @  30.9.2008,  09:21 Найти цитируемый пост)
ммм... так то спасибо конечно, но хотелось бы разобраться самому( к тому же код компилится с ошибками)

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


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

PM MAIL   Вверх
rthsobakas
Дата 30.9.2008, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 562
Регистрация: 20.9.2007

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



сначала заставь код компилироваться, а потом задавай вопросы, что не понятно
ну там мелкие касяки  были с точкой и запятой я их убрал , с ворнингами но скомпилилось. Ну и что код все равно сложный слишком. Сложные типы, структуры какие то...

Это то же самое что какой нить чувак попросил бы привести пример сложения двух чисел на паскале
что то типо
Код

uses crt;
var
a,b,sum:byte;
begin
 sum:=a+b;
end.

 а ему на встроенном асме через сопроцессор показали)))
Он бы тоже офигел немного наверно)))

Прочитай моё предпоследнее сообщение(это последнее), там я выразил суть проблемы. Если хочешь помочь лучше скажи что в моем(последнем) коде не так... И все

PM   Вверх
MAKCim
Дата 30.9.2008, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



rthsobakas, 
у тебя мешанина с выводом в файл
открывай файл в main() и делай синхронизацию при записи через flock()



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

PM MAIL   Вверх
rthsobakas
Дата 30.9.2008, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 562
Регистрация: 20.9.2007

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



ммммм сделал как у тебя

Код

#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#define N 3
#define M 10

int count=0;
static int fd;
void catcher1()
{
int i;
count++;
 char buffer[20]={"f"};

    flock(fd, LOCK_EX);
    for (i = 0; i < M; ++i) {
        flock(fd, LOCK_EX);
        write(fd, buffer,strlen(buffer));
        flock(fd, LOCK_UN);}
flock(fd, LOCK_EX);
write(fd, "\n");
flock(fd, LOCK_UN);
}




int main(){
pid_t pid2,pid3;
int st,j;

    if ((fd = open("AAAAA.txt", O_CREAT | O_RDWR | O_EXCL)) < 0) {
        perror("open");
        return -1;
    }

printf(" начало...\n");
pid2=fork();
if (pid2==0){
signal(SIGUSR1,catcher1);
}


pid3=fork();
if (pid3==0){
signal(SIGUSR1,catcher1);
}


kill(pid2,SIGUSR1);

kill(pid3,SIGUSR1);
close(fd);
printf(" Программа закончена...");
return 0;


в AAAAA.txt"
результат
ffffffffff
ffffffffff
ffffffffff
ffffffffff

То есть 4  раза он шпарит кэтчер,а надо два потому что
kill(pid2,SIGUSR1);
kill(pid3,SIGUSR1);
тока два вызова

И ещё почему то  стали нужны права супер пользователя чтобы фаил посмотреть(((

Добавлено через 2 минуты и 26 секунд
может где то wait надо написать? такое чувство что потомки повторяются

PM   Вверх
MAKCim
Дата 30.9.2008, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Код

#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#define N 3
#define M 10
int count=0;
static int fd;
void catcher1()
{
int i;
count++;
 char buffer[20]={"f"};
 flock(fd, LOCK_EX);
    for (i = 0; i < M; ++i) {
        write(fd, buffer,strlen(buffer));
   }
write(fd, "\n");
flock(fd, LOCK_UN);
}
int main(){
pid_t pid2,pid3;
int st,j;
    if ((fd = open("AAAAA.txt", O_CREAT | O_RDWR | O_EXCL)) < 0) {
        perror("open");
        return -1;
    }
printf(" начало...\n");
pid2=fork();
if (pid2==0){
signal(SIGUSR1,catcher1);
while (1) pause();
}
pid3=fork();
if (pid3==0){
signal(SIGUSR1,catcher1);
while (1) pause();
}
kill(pid2,SIGUSR1);
kill(pid3,SIGUSR1);
close(fd);
printf(" Программа закончена...\n");
return 0;
}



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

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


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 562
Регистрация: 20.9.2007

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



капец , я так и знал что где то подстава
оказывается все дело в
Код

while (1) pause();


Ещё один вопрос и я отвалю)))


Fork создает процесс, а как процесс убить? Просто я читал про wait и  exit они типо убивать должны. Я че то с ними экспериментировал , кроме Ворнингов компилятора они ниче не изменили...

То есть смотри

если я хочу убить pid2 и pid3, то опять по аналогии писать надо KILL(pid2,SIGUSR2);(в родителе) и signal(SIGUSR2,ubit); (в потомке) и писать ф-ию UBIT, а в ней exit(0);?
и в родителе вместо return 0 писать exit(0)? так получается?
PM   Вверх
MAKCim
Дата 30.9.2008, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(rthsobakas @  30.9.2008,  15:03 Найти цитируемый пост)
Fork создает процесс, а как процесс убить?

в родителе wait()
в дочернем процессе _exit()


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

PM MAIL   Вверх
rthsobakas
Дата 5.10.2008, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 562
Регистрация: 20.9.2007

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



Вообщем вот конечный вариант

Код

/*Процесс 1 открывает фаил и порождает 2 и 3 потомка, процесс 1 с интервалом в 1 сек по очереди посылает Н сигналов птоомкам 2 3,
которые пишут М символов в фаил,
Потом процесс убмвает потомков*/
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#define N 3
#define M 10
int count=0;
static int fd;
FILE *f;

void catcher1()
{
int i;
count++;
 char ch=(char)(count+100);
 char buffer[20]={ch};
 flock(fd, LOCK_EX);
    for (i = 0; i < M; ++i) {
        write(fd, buffer,strlen(buffer));
   }
write(fd, "\n");
flock(fd, LOCK_UN);
}

void catcher2()
{
wait();
}


/*Главная функия*/
int main(){
pid_t pid2,pid3;//процессы
int st,j;
char c;
// открываем фаил
    if ((fd = open("AAAAA.txt", O_CREAT | O_RDWR | O_EXCL)) < 0) {
        perror("open");
        return -1;
    }
printf(" Begin...\n");
pid2=fork();//создали потомка 1
if (pid2==0){
signal(SIGUSR1,catcher1);
signal(SIGUSR2,catcher2);
while (1) pause();
}
pid3=fork();//создали потомка 2
if (pid3==0){
signal(SIGUSR1,catcher1);
signal(SIGUSR2,catcher2);
while (1) pause();
}
int i;
for (i = 0; i < N; ++i){
printf(" wait...%d\n",i);
sleep(1);
kill(pid2,SIGUSR1);//послали 1 сигнал
printf(" wait...%d\n",i);
sleep(1);
kill(pid3,SIGUSR1);//послали 2 сигнал
}
kill(pid2,SIGUSR2);//послали 1 сигнал
kill(pid3,SIGUSR2);//послали 2 сигнал

printf(" Program over...\n");
close(fd);

if ((f=fopen("AAAAA.txt","r"))==0) {printf("file not open!\n");return 0;}
while (!feof(f))
{
c=getc(f);printf("%c",c);
}
fclose(f);
return 0;
} 



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

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

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


 




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


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

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