0 / 0 / 0
Регистрация: 06.03.2018
Сообщений: 30

Проблема с синхронизацией процессов

08.12.2018, 22:58. Показов 965. Ответов 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
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
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
 
#define MAX_CLIENTS 4
#define ADRESS "MySocket"
 
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
int main(){
    int sock, newsock, amount, shmid;
    struct sockaddr_un sock_adress;
    if((shmid = shmget(IPC_PRIVATE, 256, IPC_CREAT | 0666)) == -1){ // выделение общей памяти
        perror("Server: ошибка выделения общей памяти");
        exit(1);
    }
    if((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){   // объявляем сокет
        perror("Server: ошибка получения дискриптора сокета");
        exit(1);
    }
    sock_adress.sun_family = AF_UNIX;
    strcpy(sock_adress.sun_path, ADRESS);
    int addr_struct_len = sizeof(sock_adress.sun_family) + strlen(sock_adress.sun_path);
    unlink(ADRESS); // удалить файл MySocket, если он существует, иначе bind возвратит ошибку.
    if(bind(sock, &sock_adress, addr_struct_len) < 0){  // связываем сокет с адресом нашего домена
        perror("Server: ошибка связывания сокета с адресом");
        exit(1);
    }
    if(listen(sock, MAX_CLIENTS) < 0){  // создаем очередь на соединение с сервером
        perror("Server: ошибка создания очереди запросов");
        exit(1);
    }
    while(1){
        if((newsock = accept(sock, NULL, NULL)) < 0){   // создаем новый сокет для общения с сервером
            perror("Server: ошибка доступа");
            exit(1);
        }
        pid_t pid = fork();
        if(pid == -1){
            perror("Server: ошибка создания процесса выполнения запроса");
            exit(1);
        }
        else if(pid == 0){
            int res = 0;
            do{
                res = pthread_mutex_trylock(&mutex);
            }while(res != 0);
            char* shared_memory = (char*) shmat(shmid, (void*)0, 0); // подключение к сегменту общей памяти
            amount = atoi(shared_memory);
            char bufi[11], bufo[11];
            int bytes_read = recv(newsock, bufi, sizeof(bufi), 0);
            if(bytes_read > 0){
                int numb = atoi(bufi);
                printf("Пришло число: %d\n", numb);
                amount += numb; 
                printf("Сумма равна: %d\n", amount);
                sprintf(bufo, "%d", amount);
                send(newsock, bufo, sizeof(bufo), 0);
                close(newsock);
            }
            sprintf(shared_memory, "%d", amount);
            shmdt(shared_memory);   // отстыковывание сегмента общей памяти
            pthread_mutex_unlock(&mutex);
            exit(0);
        }
    }
    shmctl(shmid, IPC_RMID, 0); // удаление сегмента общей памяти
    close(sock);
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.12.2018, 22:58
Ответы с готовыми решениями:

проблема с синхронизацией Lotus Traveler
День добрый! Такая проблемка возникла: Существует две учетные записи, ссылающиеся на однин почтовый файл, обе имеют internet адрес и...

STM32F429 + LTDC+ VGA - проблема с синхронизацией.
Купил отладочную плату Core429I (на ней установлены STM32F429IGT6 и SDROM IS42S16400J). Изготовил для нее плату с R-2R ЦАП и разъемом для...

Проблема с GetProcesses() и поиском процессов
К сожалению функция GetProcesses() возвращает только список процессов того пользователя под которым запущена программа. Например если...

1
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
09.12.2018, 14:10
Тут достаточно хранить сумму как число и использовать __atomic_add_fetch().
Если очень хочется мьютекс, то создавайте его в разделяемой памяти (кстати shmat() достаточно сделать 1раз до fork) с атрибутом PTHREAD_PROCESS_SHARED
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.12.2018, 14:10
Помогаю со студенческими работами здесь

Проблема с удалением фоновых рабочих процессов
Здравствуйте! Проблема с удалением фоновых рабочих процессов. В &quot;postgresql.config&quot;, параметр &quot;max_worker_processes&quot;...

Читалка с синхронизацией
люблю книжки почитать на планшете и телефоне, но планшет андроидный, а телефон - виндофоновский, если ли какая то читалка на обоих...

Счетчик с синхронизацией с сервером
Делаю прогу на Delphi 7 хочу сделать ограниченное использование, раз в 24 часа, по московскому времени, нужна синхранизация с сервером,...

Странность с вертикальной синхронизацией
Доброго вечера. Хотел описать свою проблему с которой уже борюсь почти с покупки ПК. ПК обновить я решил примерно год назад на такой вот...

Локальная БД с синхронизацией с сетевой БД
Всем доброго времени суток. Есть вопрос как правильно реализовать следующую схему. В программе забивается БД и храниться локально, а...


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

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

Новые блоги и статьи
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru