Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 06.03.2018
Сообщений: 30

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

08.12.2018, 22:58. Показов 954. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru