Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 Аватар для Dizark
25 / 25 / 16
Регистрация: 12.04.2013
Сообщений: 85

Передача указателя через сигнал

16.01.2014, 15:00. Показов 879. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.

Есть процесс, который создает область разделяемой памяти и порождает дочерний процесс, которому сообщает ключ к этой области. Т.е. оба процесса могут через эту память обмениваться данными.

Дочерний процесс время от времени вносит в эту память какие-то значения и кидает сигнал родителю, мол обрабатывай.

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

В общем-то в принципе почти это все получилось, только вот почему то приходит указатель меньший на 0х1000, чем есть на самом деле.

Вот код родительского процесса:
Кликните здесь для просмотра всего текста
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
char *basket_mem_base;
int basket_shmid;
key_t basket_key;
pid_t ourPid;                                                       // наш PID
 
char* SharedMemoryAllocate (key_t key, int size, int *id)
{
    char *addr;
 
    *id = shmget (key, size, IPC_CREAT | 0666);
    if (*id < 0)
    {
        perror ("Error allocating shared memory block");
        exit (1);
    }
 
    addr = shmat (*id, NULL, 0);
    if (!addr)
    {
        perror ("Error attaching shared memory block");
        exit (2);
    }
 
    return addr;
}
 
void Randomize (void)
{
    struct tm randtime;
    int seed;
 
    mktime (&randtime);
    seed = randtime.tm_sec + randtime.tm_min + randtime.tm_hour;
 
    srand (seed);
}
 
void StartBasketMon (key_t key, int size, pid_t pid)
{
    pid_t npid;
 
    char *argBas[10];
    char tempKey[10];
    char tempPid[10];
    char tempSize[10];
 
    sprintf (tempKey, "0x%x", key);
    sprintf (tempPid, "%d", pid);
    sprintf (tempSize, "%d", size);
 
    argBas[0] = BASKETMON_NAME;
    argBas[1] = "-shk";
    argBas[2] = tempKey;
    argBas[3] = "-shs";
    argBas[4] = tempSize;
    argBas[5] = "-pid";
    argBas[6] = tempPid;
    argBas[7] = (char *)0;
 
    npid = fork ();
    if (npid == 0)
        execv (BASKETMON_PATH, argBas);
}
 
void workSig_Handler (int sig, siginfo_t *siginfo, void *context)
{
    sigset_t s_set;
    char *p;
 
    if (sigemptyset (&s_set)) return;
 
    if (sigaddset (&s_set, SIGUSR1)) return;
 
    if (sigprocmask (SIG_BLOCK, &s_set, NULL)) return;
 
    // Собственно сам обработчик
    printf ("Получен сигнал SIGUSR1.\n");
    printf ("Отправил PID: %d UID: %d\n", siginfo->si_pid, siginfo->si_uid);
    printf ("Приаттачен указатель на область в памяти. [%p].\n", siginfo->si_ptr);
 
    p = siginfo->si_ptr;
 
    printf ("%s", p);
 
    if (sigprocmask (SIG_UNBLOCK, &s_set, NULL)) return;
}
 
int main (int argc, char *argv[])
{
    struct sigaction work_sig;
 
    bzero (&work_sig, sizeof (struct sigaction));
    work_sig.sa_sigaction = &workSig_Handler;
    work_sig.sa_flags = SA_SIGINFO;
    sigaction (SIGUSR1, &work_sig, NULL);
 
    // Генерируем ключ
    Randomize ();
    basket_key = rand ();
 
    // Узнаем свой пид
    ourPid = getpid ();
 
    // Создаем область памяти
    basket_mem_base = SharedMemoryAllocate (basket_key, sizeof (plate_t) * MAXPLATE, &basket_shmid);
    *basket_mem_base = 0;
 
    // Запускаем монитор корзины
    StartBasketMon (basket_key, sizeof (plate_t) * MAXPLATE, ourPid);
 
    while (1)
    {
        printf ("нихрена не делаем\n");
        sleep (1);
    }
 
    return 0;
}


А вот код дочернего процесса:
Кликните здесь для просмотра всего текста
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
key_t key;
int sh_size;
pid_t pid;
 
char *shared_mem_base;
int shmid;
 
void GetSharedMemory (key_t key, int size)
{
    // Подключаемся к нашей области памяти
    shmid = shmget (key, size, 0666);
    if (shmid < 0)
    {
        perror ("Get memory error");
        exit (3);
    }
 
    shared_mem_base = shmat (shmid, NULL, 0);
}
 
int main (int argc, char *argv[])
{
    int n;
 
    // Парсим ключики
    for (n = 1; n < argc; n++)
    {
        if (strcmp (argv[n], "-shk") == 0)
        {
            // Ключ указывающий ключ к общей памяти
            sscanf (argv[n+1], "%x", &key);
            n++;
        }
        else if (strcmp (argv[n], "-shs") == 0)
        {
            // Ключ указывающий на размер общей памяти
            sh_size = atoi (argv[n+1]);
            n++;
        }
        else if (strcmp (argv[n], "-pid") == 0)
        {
            // Ключ указывающий на ПИД родительского процесса
            pid = atoi (argv[n+1]);
            n++;
        }
    }
 
    // Подключаем область общей памяти, для общения с ядром
    GetSharedMemory (key, sh_size);
 
    while (1)
    {
        union sigval value;
        sleep (10);
        strcpy (shared_mem_base, "А вот вам данные из другого процесса.\n");
        value.sival_ptr = shared_mem_base;
        sigqueue (pid, SIGUSR1, value);
    }
 
    return 0;
}


При отладке родителя получается так: он создает область памяти по адресу 0х4100f000
Дочерний процесс также корректно получает этот адрес (т.к. видно, что значения ячеек памяти начиная с этого адреса дочерним процессом поменялись).
А вот с сигналом приходит указатель на область 0x4100e000. Ну и собственно изза этого дальше ничего уже и не работает.

Добавлено через 46 минут
Дело было не в бобине...

Дочерний процесс приаттачивает память уже по адресу 0x4100e000.
А с сигналом все передаётся правильно.

Только почему возникло смещение?..

Добавлено через 3 минуты
Получается что одна и таже область памяти для родителя лежит по адресу 0х4100f000, а для дочернего по адресу 0х4100e000
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.01.2014, 15:00
Ответы с готовыми решениями:

Передача указателя из родительского процесса в дочерний
Здравствуйте! Стоит следующая задача. Есть процесс, который перехватывает пакеты из сети и сохраняет каждый пакет в структуру. Из этих...

Передача указателя на сигнал
Добрый день =) Перевожу программу с делфи на Qt. В делфи передавал указатели на функции с помощью записей(структур) RR = record ...

Передача указателя на класс через SendMessage
Приветствую. Не получается передать указатель на экземпляр класса через SendMessage. Передаю так: WebView* web_view; web_view =...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.01.2014, 15:00
Помогаю со студенческими работами здесь

Передача указателя на объект класса через this
Всем участникам форума горячий ПРИВЕТ! Вопрос такой. cl.h class cl { public: void cl(); int a; private: DWORD...

Передача указателя
Здравствуйте! Форумчане, очень нужна помощь..:cry: В общем ситуация такова: написана программа, нужно переделать её так, чтобы в...

передача указателя
какой способ передачи указателя наиболее быстрый? int a = 1; int *b= &amp;a; wav.set_windows((int*) b); или int a = 1; ...

Передача указателя в функцию
Здраствуйте. Если не охота читать гору текста то этот абзац + последущий за ним код можете пропустить. Задали на лабе сделать некий...

Передача указателя функции
Друзья! Need help! Есть пример &quot;Переменный список параметров указателей&quot;. В функции подсчитываем среднее арифметическое. Причем,...


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

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Вывод данных через динамический список в справочнике
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru