Форум программистов, компьютерный форум CyberForum.ru

IPC Linux - C++ Linux

Восстановить пароль Регистрация
 
Fatallight
0 / 0 / 0
Регистрация: 26.09.2012
Сообщений: 3
03.12.2016, 10:55     IPC Linux #1
Приветствую. Занялся изучением Inter-process communication.
Цель написать программу для синхронизации 3 процессов (не потоков в 1 процессе).
Суть программы должна быть такой:
запускается 3 процесса.
каждый из процессов, кроме последнего, ждёт пока все процессы-соседи запишут данные в общую память.
последний из записавших отправляет сигнал процессам-соседям продолжать.

код программы создающей общую память:


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
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
 
unsigned const int SIZE = 0x1000;
 
struct shmem
{
    unsigned short int buff [SIZE];
    pthread_mutex_t mutex;
    pthread_mutex_t cond_mutex;
    pthread_cond_t cond;
};
 
 
//программа для создания общей памяти.
int main(int argc, char** argv)
{
    pthread_mutexattr_t mattr;
    pthread_mutexattr_init(&mattr);
    pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
    
    pthread_condattr_t cattr;
    pthread_condattr_init(&cattr);
    pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
    
    int flags = 0, mods = 0;
    flags |= O_RDWR | O_CREAT | O_EXCL;
    mods |= S_IRUSR | S_IWUSR;
    int fd = shm_open("shmem", flags, mods);
    if(fd == -1)
    {
        shm_unlink("shmem");
        fd = shm_open("shmem", flags, mods);
        puts("Память пересоздана!");
    }
    if(fd == -1)
    {
        printf("[%d] ERROR пересоздать память не удалось\n",fd);
        exit(-1);
    }
    ftruncate(fd, sizeof(shmem));
    void* addr_shmem = mmap(NULL, sizeof(shmem), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    shmem* p_shmem = static_cast<shmem*> (addr_shmem);
    
    pthread_mutex_init(&p_shmem->mutex, &mattr);
    pthread_mutex_init(&p_shmem->cond_mutex, &mattr);
    pthread_cond_init(&p_shmem->cond, &cattr);
    for(unsigned int i=0;i < SIZE;i++)
        p_shmem->buff[i]=0x5ACF;
    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
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
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
 
unsigned const int SIZE = 0x1000;
unsigned const int OFFSET = 320;
unsigned const int SIZE_PACK = 32;
int proc = -1;
int proc1 = -1;
int proc2 = -1;
 
struct shmem
{
    unsigned short int buff [SIZE];
    pthread_mutex_t mutex;
    pthread_mutex_t cond_mutex;
    pthread_cond_t cond;
};
 
int main(int argc, char** argv)
{   
    // разбор параметров. параметром передаётся номер процесса.
    if (argc != 2)
    {
        printf("Не указан номер процесса");
        exit(0);
    }
    else
    {
        proc = atoi(argv[1]);// проверка ввода не осуществляется.
        printf("процесс = [%d] аргумент = [%s]\n", proc, argv[1]);
    }
    
    // получить общщую память.
    struct stat stat;
    int fd = shm_open("shmem", O_RDWR, S_IRUSR | S_IWUSR);
    fstat(fd, &stat);
    printf("размер памяти = [%ld]\n", stat.st_size);
    void* addr_shmem = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    shmem* p_shmem = static_cast<shmem*> (addr_shmem);
    close(fd);
 
    // назначение соседних процессов.
    switch(proc)
    {
        case 0:
            proc1 = 1;
            proc2 = 2;
        break;
        case 1:
            proc1 = 0;
            proc2 = 2;
        break;
        case 2:
            proc1 = 0;
            proc2 = 1;
        break;
        default:
            puts("нельзя указывать номер процесса больше 2");
            exit(0);
    }
 
    unsigned long int count = 0;
    while(true)
    {
        pthread_mutex_lock(&p_shmem->mutex);
 
        for(unsigned int i=0;i<SIZE_PACK;i++)
            p_shmem->buff[SIZE_PACK*proc+i] = count;// записать данные(номер вхождения в цикл)
        p_shmem->buff[OFFSET+proc] = 0xAAAA;// записать значение что процесс записал все данные.
        printf("процесс [%d] записал все данные\n", proc);
        if(p_shmem->buff[OFFSET+proc1] == 0xAAAA && p_shmem->buff[OFFSET+proc2] == 0xAAAA)//проверить готовы ли соседние процессы
        {
            puts("Все процессы записали данные. ПУСК!!!");
            printf("[%X][%X][%X]\n",p_shmem->buff[OFFSET+proc],p_shmem->buff[OFFSET+proc1],p_shmem->buff[OFFSET+proc2]);
            p_shmem->buff[OFFSET+proc1] = 0x5555;// сбросить флаги готовности записи всех процессов.
            p_shmem->buff[OFFSET+proc2] = 0x5555;
            p_shmem->buff[OFFSET+proc] = 0x5555;
            
            pthread_mutex_lock(&p_shmem->cond_mutex);
            pthread_cond_broadcast(&p_shmem->cond);//отправить сигналы всем соседним процессам - продолжать.
            pthread_mutex_unlock(&p_shmem->cond_mutex);
        }
        else
        {
            puts("Не все процессы записали данные. WAIT!!!");
            printf("[%X][%X][%X]\n",p_shmem->buff[OFFSET+proc],p_shmem->buff[OFFSET+proc1],p_shmem->buff[OFFSET+proc2]);
            
            pthread_mutex_unlock(&p_shmem->mutex);
            
            pthread_mutex_lock(&p_shmem->cond_mutex);
            pthread_cond_wait(&(p_shmem->cond), &(p_shmem->cond_mutex));// остановить процесс до получения сигнала от соседнего процесса.
            pthread_mutex_unlock(&p_shmem->cond_mutex);
            
            pthread_mutex_lock(&p_shmem->mutex);
            
        }
        //вывод данных после записи всех процессов.
        puts("Данные");
        for(unsigned int i=0;i<SIZE_PACK;i++)
            printf("%X ", p_shmem->buff[SIZE_PACK*proc+i]);
        puts("");
        for(unsigned int i=0;i<SIZE_PACK;i++)
            printf("%X ", p_shmem->buff[SIZE_PACK*proc1+i]);
        puts("");
        for(unsigned int i=0;i<SIZE_PACK;i++)
            printf("%X ", p_shmem->buff[SIZE_PACK*proc2+i]);
        puts("");
        pthread_mutex_unlock(&p_shmem->mutex);
        count++;
    }
    return 0;
}
Вроде учёл всё, но возникает ситуации:
1) когда все три процесса начинают ждать-соседей.
2) происходит рассинхронизация в данных процессов (переменная count).

Прошу помощи. Что я делаю не так? почему такие ситуации возникают?
ниже ссылка на скриншот консоли.
IPC Linux
 Комментарий модератора 

Изображения загружайте на форум.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.12.2016, 10:55     IPC Linux
Посмотрите здесь:

[C++]Bluetooth и Linux C++ Linux
Linux / C++ C++ Linux
C++ Linux Linux c++
C++ Linux Си на Linux
Консоль в linux C++ Linux
C++ Linux Open gl c++ linux
C++ Linux Open gl c++ linux
C++ Linux Компиляция Builder'овского проекта под Linux, (и освоение Linux после Builder'a)
Сокеты в Linux C++ Linux
WinAPI в Linux) C++ Linux
C++ Linux Linux OpenGL 2.0
Перевод на C++ Linux C++ Linux

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

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

Текущее время: 02:27. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru