Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.76/29: Рейтинг темы: голосов - 29, средняя оценка - 4.76
0 / 0 / 0
Регистрация: 13.12.2013
Сообщений: 3
1

Сигналы для синхронизации процессов

13.12.2013, 09:00. Показов 5621. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день.
Мне нужно написать программу для синхронизации процессов с помощью сигналов под Солярис. Надо использовать sigaction, sigprocmask, sigsuspend.
Если подробнее, то смысл в том, чтобы процесс создал потомка, который, например, будет считать какую-то линейную функцию. А родитель будет считать квадратные корни. Когда один из них заканчивает расчёт, он отправляет другому сигнал. Тот, кто первым посчитал, ждёт, пока посчитает второй. После этого они в своих циклах переходят к следующим расчётам.
В общем мне нужно исправить ошибки в коде:
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
#include <signal.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <math.h>
 
void myact1(int sig)
{
   sigset_t set1;
   sigemptyset(&set1);
   sigaddset(&set1,sig);
   sigprocmask(SIG_BLOCK,&set1,NULL);
   printf("child: in signal\n");
   sigprocmask(SIG_UNBLOCK,&set1,NULL);
}
 
void myact2(int sig)
{
  sigset_t set2;
  sigemptyset(&set2);
  sigaddset(&set2,sig);
  sigprocmask(SIG_BLOCK,&set2,NULL);
  printf("daddy: in signal\n");
  sigprocmask(SIG_UNBLOCK,&set2,NULL);
}
 
int main()
{
   int CPID,PID,stt;
 
   if((CPID=fork())==0)
   {
      int i,res1;
      printf("Hi I'm child\n");
      struct sigaction act1;
      sigset_t set1;
      sigemptyset(&set1);
      sigaddset(&set1,SIGUSR1);
      memset(&act1,0,sizeof(act1));
      act1.sa_handler= myact1;
      act1.sa_mask=set1;
      sigaction(SIGUSR1,&act1,NULL);
      sigemptyset(&set1);
      for(i=0;i<10;i++)
      {
       res1=i*10+124+98*i;
       printf("child result=%d\n",res1);
       kill(PID,SIGUSR2);
       printf("child waits\n");
       sigsuspend(&set1);
      }
      exit(0);
   }
 
   sleep(2);
   printf("Hi I'm daddy\n");
   struct sigaction act2;
   sigset_t set2;
   sigemptyset(&set2);
   sigaddset(&set2,SIGUSR2);
   memset(&act2,0,sizeof(act2));
   act2.sa_handler=myact2;
   act2.sa_mask=set2;
   sigaction(SIGUSR2,&act2,NULL);
   sigemptyset(&set2);
   int k,res2;
   for(k=0;k<10;k++)
  {
      res2=k*sqrt(16);
      printf("daddy result=%d\n",res2);
      kill(CPID,SIGUSR1);
      printf("daddy waits");
      sigsuspend(&set2);
   }
   sleep(1);
   kill(CPID,SIGKILL);
   exit(0);
}
Пока у меня процессы после первого прохода своих циклов встают в бесконечное ожидание:
Если не трудно, подскажите, как можно это исправить.
Миниатюры
Сигналы для синхронизации процессов  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.12.2013, 09:00
Ответы с готовыми решениями:

Взаимодействие процессов. Сигналы
Создать дерево процессов 1-&gt;(2,3) 2-&gt;(4,5) 5-&gt;6 6-&gt;(7,8) Процессы непрерывно...

Создание процессов - Сигналы
Добрый вечер, форумчане! Начал осваивать с++ под linux не так давно. Не могу разобраться до конца...

Задача упорядочивания (синхронизации) процессов
Всем доброго времени суток! Есть вопрос по синхронизации обработки данных. В модель поступают...

Понятие синхронизации потоков и процессов. Семафоры и мьютексы
Хотелось бы обсудить и уточнить некоторые понятия: 1. Корректно ли следующее утверждение....

6
4 / 4 / 7
Регистрация: 18.11.2013
Сообщений: 53
13.12.2013, 14:27 2
Тебе по ТЗ нужно использовать sigaction, sigprocmask, sigsuspend, или можно без блокировок сигналов?
0
0 / 0 / 0
Регистрация: 13.12.2013
Сообщений: 3
13.12.2013, 17:27  [ТС] 3
Да, у меня в задании говорится так. Всё дело в sigprocmask в функциях обработки сигналов?
0
1241 / 960 / 379
Регистрация: 02.09.2012
Сообщений: 2,936
14.12.2013, 00:44 4
Смотрел по диагонали. Применение sigsuspend показалось сомнительным - не совосем то действие. Замените на sigwait и поставьте ожидание соответ. сигнала от соседа. Потому что сейчас они у вас в дедлок становатся, потому что ждут неизвестно чего друг от друга.
0
0 / 0 / 0
Регистрация: 13.12.2013
Сообщений: 3
14.12.2013, 10:37  [ТС] 5
Исправил sigsuspend на sigwait, дедлок исчез, но процессы не ждут друг друга. Сначала потомок выполняет все свои циклы, потом отец. А вывод должен чередоваться.
Миниатюры
Сигналы для синхронизации процессов  
0
4 / 4 / 7
Регистрация: 18.11.2013
Сообщений: 53
16.12.2013, 10:40 6
функция fork создает полную независимую копию, но как узнать где созданная копия(Chiild) или оригинал(parent) , родителю он возвращает PID ребенка, а ребенку 0, судя по твоему коду ребенок у тебя выполнит сначало блок if, а потом нижний код, а родитель не попадет под условие if и будет выполнять сразу нижний код! проверь может проблема в этом
0
1241 / 960 / 379
Регистрация: 02.09.2012
Сообщений: 2,936
17.12.2013, 16:30 7
А кто у вас PID инициализирует? чему оно равно? кому вы сигнал посылаете?

Добавлено через 23 часа 57 минут
Посмотрел внимательно ваш код. Попытался сделать как должно работать по моим представлениям. Не проверял - может накосячил где-то.

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
/* инклуды не помню какие нужны (man в помощь) */
#include <stdio.h>
#include <signal.h>
 
/* заводим отдельные функции для родителя и потомка - так удобнее смотреть */
void parent(pid_t childID);
void child(pid_t parentID);
 
/* единая маска для нашего сигнала - для синхронизации должно быть достаточно SIGUSR1 */
sigset_t maskusr1;
 
/* Наш пустой обработчик сигнала */
void signal_handler(int sig) {
    return;
}
 
/* Блокируем прием сигнала процессом */
void lock_signal(void) {
    sigprocmask(SIG_BLOCK, &maskusr1, NULL);
}
 
/* Разблокируем прием сигнала процессом */
void unlock_signal(void) {
    sigprocmask(SIG_UNBLOCK, &maskusr1, NULL);
}
 
/* Старт здесь */
int main(int argc, char *argv[]) {
    struct sigaction sa;
    pid_t pID;
 
    /* Формируем маску, состояющую из одного сигнала и сразу говорим процессу, что сигнал заблокирован,
    а значит все посылы этого сигнала нам, должны ожидать доставки (pending) */
    sigemptyset(&maskusr1);
    sigaddset(&maskusr1, SIGUSR1);
    lock_signal();
 
    /* Устанавливаем обработку сигнала */
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = signal_handler;
    sigaction(SIGUSR1, &sa, NULL);
 
    /* Размножаемся */
    pID = fork();
    /* Проверяем кто мы и идем в соотв. функцию */
    /* При этом передаем идент. процесса-соседа */
    if (pID < 0) {
        printf("fork() errorno = %d\n", errno);
        return 1;
    } else if (pID > 0) {
        parent(pID);
    } else {
        child(getppid());
    }
 
    return 0;
}
 
/* Родитель */
void parent(pid_t childID) {
    int i, res, sig;
    printf("Hi! I'm parent with PID = %d (my child is %d)\n", getpid(), childID);
 
    for (i = 0; i < 1; i++) {
        res = i * sqrt(16);
        printf("parent result = %i\n", res);
        kill(childID, SIGUSR1);
        printf("parent waits\n");
        unlock_signal();
        sigwait(&maskusr1, &sig);
        lock_signal();
    }
    printf("Parent finished\n");
}
 
/* Потомок */
void child(pid_t parentID) {
    int i, res, sig;
    printf("Hi! I'm child width PID = %d (my parent is %d)\n", getpid(), parentID);
 
    for (i = 0; i < 1; i++) {
        res = i * 10 + 124 + 98 * i;
        printf("child result = %i\n", res);
        kill(parentID, SIGUSR1);
        printf("child waits\n");
        unlock_signal(); /* Разблокировали получение сигнала */
        sigwait(&maskusr1, &sig); /* Дождались получения */ 
        lock_signal(); /* Снова заблокировали получение сигнала */
    }
    printf("Child finished\n");
}
0
17.12.2013, 16:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.12.2013, 16:30
Помогаю со студенческими работами здесь

Что значат эти сигналы (vmware w, bios сигналы)?
Создаю машину с Kali, при запуске если стоит bios 1 длинный сигнал , если uefi 1 длинный и 1...

Программа для синхронизации
Всем привет! Такая ситуация: мне надо выбрать самому проект для курсовой работы по ООП. Ничего не...

Софт для синхронизации
У меня имеется ноутбук с установленной Ubuntu и системник с двумя монитрами под Windows. Мне...

Триггер для синхронизации полей
Здравствуйте, помогите составить триггер для синхронизации полей в бд. Дано - 1 бд, в ней 2...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru