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

Выборка данных из общей памяти

07.11.2013, 19:56. Показов 967. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
пишу пул процессов для сервера,пул располагается в общем сегменте памяти,с которым все процессы и будут работать,для теста просто пробую добавить один процесс в пул и затем вывести его pid,но именно в момент, когда я пытаюсь это сделать - происходит сегментэйшен фолт(после 129 строки в коде) :

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <semaphore.h>
#include <sys/shm.h>
#include "headers/processpool.h"
#include "headers/debug.h"
 
#define DEBUG
#ifdef DEBUG
#define TRACE printf("%s %d\n", __FILE__,__LINE__);
#else
#define TRACE
#endif
 
typedef struct shared_use
{
    sem_t sems[10];
    proc_pool_t pool;
    queue_t procq;
    entry_t procesess[10];
 
} shared_use;
 
void queue_test();
 
entry_t proc;
pid_t fork_result;
entry_t *centry;
 
int main()
{
    void *shared_memory = (void *)0;
    shared_use *shared_stuff;
    int shmid, res , i;
 
    shmid = shmget((key_t)123, sizeof(shared_use), 0666 | IPC_CREAT);
    if(shmid == -1)
    {
        fprintf(stderr,"shmget failed\n");
        exit(EXIT_FAILURE);
    }
 
    shared_memory = shmat(shmid, (void *)0, 0);
    if(shared_memory == (void *)-1)
    {
        fprintf(stderr, "shmat failed\n");
        exit(EXIT_FAILURE);
    }
 
    shared_stuff = (shared_use *)shared_memory;
 
    for(i; i < 10; i++)
    {
        res = sem_init(&shared_stuff->sems[i],1,0);
        if(res != 0)
        {
            perror("Semaphore init failed");
            exit(EXIT_FAILURE);
        }
    }
    printf("sems init ok\n");
    fflush(stdout);
    shared_stuff->pool.proc_queue = &shared_stuff->procq;
    shared_stuff->pool.proc_queue->head = NULL;
    shared_stuff->pool.proc_queue->tail = NULL;
    shared_stuff->pool.proc_queue->count = 0;
 
    i = 0;
    for(i; i < 1; i++);
    {
        fork_result = fork();
        if(fork_result == -1)
        {
            fprintf(stderr,"Fork failure\n");
            exit(EXIT_FAILURE);
        }
 
        if(fork_result == 0)
        {
            shmid = shmget((key_t)123, sizeof(shared_use), 0666 | IPC_CREAT);
            if(shmid == -1)
            {
                fprintf(stderr,"shmget failed\n");
                exit(EXIT_FAILURE);
            }
 
            shared_memory = shmat(shmid, (void *)0, 0);
            if(shared_memory == (void *)-1)
            {
                fprintf(stderr, "shmat failed\n");
                exit(EXIT_FAILURE);
            }
 
            shared_stuff = (shared_use *)shared_memory;
            printf("child add shm ok\n");
            fflush(stdout);
 
            shared_stuff->procesess[i].entry_semaphore = &shared_stuff->sems[i];
            shared_stuff->procesess[i].proc_pid = getpid();
 
            printf("child proc init ok\n");
            fflush(stdout);
 
            add_in_tail(shared_stuff->pool.proc_queue, &shared_stuff->procesess[i]);
            printf("child proc add in queue ok\n");
            sem_post(&shared_stuff->sems[0]);
 
            while(1)
            {
                ;
            }
        }
        else
        {
            printf("child created!\n");
        }
 
    }
    TRACE
    sem_wait(&shared_stuff->sems[0]);
    TRACE
    centry = shared_stuff->pool.proc_queue->head;
 
    if(centry == NULL)
        printf("curentry == NULL\n");
    TRACE
    while(centry != NULL)
    {
        printf("free proc pid = %d\n", centry->proc_pid);
        centry = centry->next;
    }
    TRACE
    if(shmdt(shared_memory) == -1)
    {
        fprintf(stderr,"shmdt failed\n");
        exit(EXIT_FAILURE);
    }
 
    if(shmctl(shmid,IPC_RMID,0) == -1)
    {
        fprintf(stderr,"shmctl(IPC_RMID) failed\n");
        exit(EXIT_FAILURE);
    }
 
    return EXIT_SUCCESS;
}
 
void queue_test()
{
    int i = 0;
    proc_pool_t mypool = get_pool();
    entry_t *pop_entry1, *pop_entry2;
    entry_t *curentry;
 
    for(i; i < 10; i++)
    {
        entry_t *entry = (entry_t *)malloc(sizeof(entry_t));
        entry->proc_pid = (pid_t)i;
        add_in_tail(mypool.proc_queue, entry);
    }
    TRACE
    pop_entry1 = pop_free_proc(mypool.proc_queue);
    pop_entry2 = pop_free_proc(mypool.proc_queue);
    TRACE
    printf("work pid = %d\n",pop_entry1->proc_pid);
    printf("work pid = %d\n",pop_entry2->proc_pid);
    printf("\n");
 
    curentry = mypool.proc_queue->head;
    while(curentry != NULL)
    {
        printf("free pid = %d\n", curentry->proc_pid);
        curentry = curentry->next;
    }
 
    printf("\n");
    TRACE
    add_in_tail(mypool.proc_queue,pop_entry1);
    add_in_tail(mypool.proc_queue,pop_entry2);
    TRACE
    curentry = mypool.proc_queue->head;
 
    while(curentry != NULL)
    {
        printf("free pid = %d\n", curentry->proc_pid);
        curentry = curentry->next;
    }
 
    printf("\n");
    printf("count = %d\n",mypool.proc_queue->count);
 
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.11.2013, 19:56
Ответы с готовыми решениями:

Создание переменных в сегменте общей памяти
Здравствуйте! Объясните непутевому мне, пожалуйста. Выделил общий сегмент памяти для...

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

Уменьшение общей памяти
Привет, уже как пару месяцев назад я купил ссд диск, вроде как на 128 гигов. Когда установил на нее...

Механизм общей памяти
Добрый вечер. Вот строка из задания:&quot;реализовать, используя механизм общей памяти, передачу данных...

13
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
07.11.2013, 20:26 2
shmget()+shmat() после fork() не нужен, ребенок и так унаследовал это от родителя, а в таком виде shmat() мапит память в другое место, и соотвественно родитель и другие дети получают указатели в никуда. Т.е. либо делаете shmat() один раз в родителе, либо используете в своих структурах не указатели, а смещения.
ЗЫ: еще можно man queue
ЗЗЫ: а зачем вообще хранить пиды?
1
65 / 37 / 3
Регистрация: 30.11.2011
Сообщений: 109
07.11.2013, 20:32  [ТС] 3
g_u_e_s_t,
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
ЗЫ: еще можно man queue
хедер
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
#ifndef PROCPOOL
#define PROCPOOL
 
typedef struct entry_t
{
  sem_t *entry_semaphore;
  pid_t proc_pid;
  struct entry_t *next;
} entry_t;
 
typedef struct queue_t
{
  entry_t *head;
  entry_t *tail;
  int count;
} queue_t;
 
typedef struct proc_pool_t
{
  queue_t *proc_queue;
} proc_pool_t;
 
void add_in_tail(queue_t *proc_queue, entry_t *newproc);
entry_t *pop_free_proc(queue_t *proc_queue);
 
#endif
реализация
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/types.h>
#include <semaphore.h>
#include <sys/shm.h>
#include "headers/processpool.h"
#include "headers/debug.h"
 
extern void add_in_tail(queue_t *proc_queue, entry_t *newproc)
{
    proc_queue->count++;
    printf("adding free proc in tail,count = %d\n",proc_queue->count);
 
    if(proc_queue->head == NULL)
    {
        proc_queue->head = newproc;
        proc_queue->tail = newproc;
    }
    else
    {
        proc_queue->tail->next = newproc;
        proc_queue->tail = newproc;
        proc_queue->tail->next = NULL;
    }
 
    if(proc_queue->head != NULL)
        printf("HEAD NOT NULL!\n");
}
 
extern entry_t *pop_free_proc(queue_t *proc_queue)
{
    entry_t *curentry;
    entry_t *return_entry;
 
    curentry = proc_queue->head;
    if (curentry != NULL)
    {
        return_entry = curentry;
    }
    if(proc_queue->head->next != NULL)
        proc_queue->head = proc_queue->head->next;
    else
    {
        proc_queue->head = NULL;
        proc_queue->tail = NULL;
    }
    proc_queue->count--;
    return return_entry;
}
то есть queue - обычная очередь

Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
ЗЗЫ: а зачем вообще хранить пиды?
ради того,чтоб вывести и убедиться,что всё работает нормально,потом уберу

большое вам спасибо,помогло
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
07.11.2013, 20:36 4
Цитата Сообщение от greenEYE Посмотреть сообщение
хедер
Ж) это был совет прочитать соответсвующий ман и использовать sys/queue.h вместо показаного.
0
65 / 37 / 3
Регистрация: 30.11.2011
Сообщений: 109
07.11.2013, 20:37  [ТС] 5
g_u_e_s_t,
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
07.11.2013, 20:38 6
А в чем идея пула? Чем это должно отличаться от традиционного pre-fork?
0
65 / 37 / 3
Регистрация: 30.11.2011
Сообщений: 109
07.11.2013, 20:42  [ТС] 7
g_u_e_s_t, пул - это ,вроде, и есть названное вами понятие

Добавлено через 1 минуту
в моём случае процессы после выполнения задачи будут не уничтожаться,а возвращаться обратно в очередь свободных процессов
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
07.11.2013, 20:46 8
А зачем тогда вообще очередь то? Я не против конечно, но просто любопытно
0
65 / 37 / 3
Регистрация: 30.11.2011
Сообщений: 109
07.11.2013, 20:56  [ТС] 9
g_u_e_s_t, ну вот нафоркаю я процессов,с каждым из них будет связан семафор,очередь будет собственно их и содержать,когда главный процесс будет принимать запрос от клиента,он отдаст задачу процессу из очереди,просто сделав sem_post семафору из очереди,в этот момент этот семафор из очереди убирается,чтобы после выполнения процесса добавить его в конец очереди,то есть такая круговая работа получится,вместо очереди можно и кольцевой список взять,да что угодно) ну я себе просто реализацию задачи таким образом представляю,если вы знаете более логичный вариант,то прошу его озвучить
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
07.11.2013, 21:14 10
Цитата Сообщение от greenEYE Посмотреть сообщение
если вы знаете более логичный вариант,то прошу его озвучить
Для этого нужно более-менее чётко понимать, что же именно Вы сделать хотите А так только абстрактно рассуждать можно. Например родитель может складывать запросы в очередь, а дети ее разгребают (писатель->читатели). Или пусть дети сами принимают запросы - т.е. вообще никаких очередей и shm если конечно не подрозумеваются какие-то общие данные.
1
65 / 37 / 3
Регистрация: 30.11.2011
Сообщений: 109
07.11.2013, 21:45  [ТС] 11
g_u_e_s_t, хотел сделать такого плана http://www.osp.ru/pcworld/2008/11/5685083/

Добавлено через 15 минут
g_u_e_s_t, а как задачу в очередь добавить? ну вот делаю я в главном процессе
C
1
2
    client_len = sizeof(client_address);
    client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address,&client_len);
что при регистрации запроса добавлять в очередь?
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
07.11.2013, 21:57 12
На цели озвученные по ссылке по-моему хорошо годиться POSIX или SYSV очереди сообщений.
Но... В сосдней теме ссылка на github где среди прочего, рядом лежит код из этого топика для тех целей проще всего отдать accept() на откуп детям т.е. обойтись вообще без shm, плясок с передачей дескриптора ребенку и прочего, семафор тоже не понадобиться если listen() сокет будет один.

Добавлено через 4 минуты
Написал, потом увидел Вашу добавку.
У Вас как я понял не "очередь заданий", а список свободных процессов. Т.е. берете процесс из этого списка, помечаете его как занятый, отдаете ему дескриптор полученный от accept() через sendmsg()
1
65 / 37 / 3
Регистрация: 30.11.2011
Сообщений: 109
07.11.2013, 22:11  [ТС] 13
g_u_e_s_t, спасибо,но я не совсем пойму,как мне процессу определённому передать дескриптор через sendmsg,если можно - приведите короткий пример,я тут ещё обнаружил такою "фичу",если её можно так назвать

этот цикл то ли выполняется только 1 раз,то ли не знаю,в общем сообщение child created только 1 раз выводится :
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
    i = 0;
    for(i; i < 10; i++);
    {
        fork_result = fork();
        if(fork_result == -1)
        {
            fprintf(stderr,"Fork failure\n");
            exit(EXIT_FAILURE);
        }
 
        if(fork_result == 0)
        {
            shared_stuff->procesess[i].entry_semaphore = &shared_stuff->sems[i];
            shared_stuff->procesess[i].proc_pid = getpid();q
 
            printf("child proc init ok\n");
            fflush(stdout);
 
            add_in_tail(shared_stuff->pool.proc_queue, &shared_stuff->procesess[i]);
            printf("child proc add in queue ok\n");
 
            while(1)
            {
                ;
            }
        }
        else
        {
            printf("child created!\n");
        }
 
    }
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
07.11.2013, 22:18 14
greenEYE, погуглите "unix fd passing"
в приведенном кусочке проблем кроме буквы q в конце 14строки не вижу
1
07.11.2013, 22:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.11.2013, 22:18
Помогаю со студенческими работами здесь

Механизм общей памяти и attach к процессу
Добрый день! Существует следующая задача.Имеется драйвер, получающий скан-код нажатой...

Клиент-сервер на основе общей памяти с использованием семафоров
Собственно задание: сервер рисует прямоугольник с заданными координатами и цветом. Клиент посылает...

Распределение данных по разным таблицам в exel при заполнении общей базы данных
При создании базы данных по оборотам компаний и формировании отчета по каждой из них, я не знаю как...

Модель распределения памяти разделами переменного размера с общей очередью, стратегия "наименее подходящий"
Здравствуйте. Получил следующее задание: Для каждой поступающей программы выделяется один из...


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

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