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

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

08.12.2018, 22:58. Показов 785. Ответов 1
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, форумчане. Пишу небольшой клиент-сервер с таким заданием: клиент посылает число, сервер отсылает обратно сумму всех чисел, принятых на данный момент, притом со стороны сервера каждый обработчик чисел - отдельный процесс.

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

Подскажите, как правильно синхронизировать процессы в моем случае? или мьютексы только с нитями работают?

Сервер:
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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.12.2018, 22:58
Ответы с готовыми решениями:

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

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

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

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

1
724 / 224 / 72
Регистрация: 01.03.2011
Сообщений: 629
09.12.2018, 14:10 2
Тут достаточно хранить сумму как число и использовать __atomic_add_fetch().
Если очень хочется мьютекс, то создавайте его в разделяемой памяти (кстати shmat() достаточно сделать 1раз до fork) с атрибутом PTHREAD_PROCESS_SHARED
0
09.12.2018, 14:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.12.2018, 14:10
Помогаю со студенческими работами здесь

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

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

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

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


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

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

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