Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/29: Рейтинг темы: голосов - 29, средняя оценка - 5.00
1 / 1 / 0
Регистрация: 19.12.2017
Сообщений: 147

Семафоры

26.05.2019, 11:21. Показов 6321. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте
Задача: разработать комплекс программ, который демонстрирует решения по-дачи «читатели-писатели». В комплекс должны входить: программа-монитор, программа-писатель, программа-читатель.
В программе мониторе можно запускать на выполнение и завершать любое количество программ-писателей и программ-читателей, отслеживать и выводить в графическом виде состояние общего для всех программ буфера
31
(Содержание буфера, состояние блокировки Состав групп читателей и писателей; очереди процессов, ожидающих регистрацию в группах), выводить информацию, которую зап-суют писатели и считывают читатели.
Программа-писатель и программа-читатель могут быть запущены на вы-полнение в нескольких экземплярах одновременно, но не более 6 вместе (читатели + писатели в любом соотношении, ограничения организовать с помо-щью объекта ядра операционной системы - Job). В буфере сохраняется тексто-е данные, объем буфера - от 10 до 20 символов.
Операции чтения и записи оформить таким образом, чтобы их выполнение занимало от 3 до 10 секунд каждая (время определяется случайным образом). Бу-фер разместить в общей для всех процессов памяти с помощью файла, что отражено в память.


Синхронизация с помощью семафор(преимущество у писателей тоесть когда пишет писатель в этот момент никто из читателей не может читать )
Не пойму как даже близко реализовать подскажите пожалуйста кто может
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.05.2019, 11:21
Ответы с готовыми решениями:

Win32 и Семафоры
Здравствуйте! Проблема: 1-й поток нормально работает. Семафор переключается. А во втором потоке - нет. Как вывести результаты со...

Критическая секция и семафоры
Посмотрите пожалуйста правильно ли я сделал программу. Нужно было написать программу, в которой при помощи семафоров оформить операцию a++...

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

22
2736 / 891 / 331
Регистрация: 10.02.2018
Сообщений: 2,128
26.05.2019, 19:37
Лучший ответ Сообщение было отмечено Lunch как решение

Решение

Студворк — интернет-сервис помощи студентам
Попробовал свой первый вариант.
При ваших условиях (обработка данных несколько секунд) запись практически не выполнима.
Несколько потоков чтения всегда забирают ресурс на себя и не оставляют шансов записи на выполнение.
Нужна RW-блокировка с приоритетом записи.
Очередь при межпроцессорном взаимодействии приляпать можно, но сложно.
Получилось сделать через два семафора. Не знаю, насколько всё правильно, но больше ничего в голову не лезет.
RW-блокировка на семафорах с потоками
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
#include <Windows.h>
#include <stdio.h>
 
// количество клиентов
const int cMaxCount = 6;
 
// общий буфер
char g_chSharedBuffer[256] = { 0 };
 
//-------------------------------------------------------------------------------------------------
// RW-блокировка с приоритетом записи
//-------------------------------------------------------------------------------------------------
class CLockRW
{
protected:
    HANDLE m_hExclusive;
    HANDLE m_hReadCounter;
 
public:
    CLockRW()
    {
        m_hExclusive = CreateSemaphore(0, 1, 1, TEXT("rwExclusive"));
        m_hReadCounter = CreateSemaphore(0, cMaxCount, cMaxCount, TEXT("rwReadCounter"));
    }
 
    ~CLockRW()
    {
        CloseHandle(m_hReadCounter);
        CloseHandle(m_hExclusive);
    }
 
    void Lock(bool bWrite)
    {
        WaitForSingleObject(m_hExclusive, INFINITE);
        if (bWrite)
        {
            for (int i=0; i<cMaxCount; i++)
                WaitForSingleObject(m_hReadCounter, INFINITE);
        }
        else
        {
            WaitForSingleObject(m_hReadCounter, INFINITE);
        }
        ReleaseSemaphore(m_hExclusive, 1, 0);
    }
 
    void Unlock(bool bWrite)
    {
        ReleaseSemaphore(m_hReadCounter, (bWrite) ? cMaxCount : 1, 0);
    }
};
 
//-------------------------------------------------------------------------------------------------
// отладочная печать в консоль
//-------------------------------------------------------------------------------------------------
void log(const char* msg, ...)
{
    static HANDLE _log = CreateMutex(0, FALSE, 0);
    WaitForSingleObject(_log, INFINITE);
 
    SYSTEMTIME st;
    GetSystemTime(&st);
    printf("%02d:%02d:%02d> <%d> ", st.wHour, st.wMinute, st.wSecond, GetCurrentThreadId());
 
    va_list vl;
    va_start(vl, msg);
    vprintf(msg, vl);
    va_end(vl);
 
    printf("\n");
 
    ReleaseMutex(_log);
}
 
 
//-------------------------------------------------------------------------------------------------
// чтение
//-------------------------------------------------------------------------------------------------
class CReader
{
protected:
    CLockRW m_rwl;
    HANDLE m_hThread;
    DWORD m_dwThreadID;
 
public:
    CReader()
    {
        m_hThread = CreateThread(0, 0, Thread, this, 0, &m_dwThreadID);
    }
 
    ~CReader()
    {
        //WaitForSingleObject(m_hThread, INFINITE);
        //CloseHandle(m_hThread);
    }
 
    static DWORD WINAPI Thread(LPVOID ptr)
    {
        return ((CReader*)ptr)->Thread();
    }
 
    DWORD Thread()
    {
        for (;;)
        {
            m_rwl.Lock(false);
 
            log("R: %s", g_chSharedBuffer);
 
            Sleep((1 + rand() % 5) * 1000);
 
            log("R: try lock");
 
            m_rwl.Unlock(false);
        }
 
        return 0;
    }
};
 
//-------------------------------------------------------------------------------------------------
// запись
//-------------------------------------------------------------------------------------------------
class CWriter
{
protected:
    CLockRW m_rwl;
    HANDLE m_hThread;
    DWORD m_dwThreadID;
    const char* m_pWriteData;
 
public:
    CWriter(const char* pWriteData) : m_pWriteData(pWriteData)
    {
        m_hThread = CreateThread(0, 0, Thread, this, 0, &m_dwThreadID);
    }
 
    ~CWriter()
    {
        //WaitForSingleObject(m_hThread, INFINITE);
        //CloseHandle(m_hThread);
    }
 
    static DWORD WINAPI Thread(LPVOID ptr)
    {
        return ((CWriter*)ptr)->Thread();
    }
 
    DWORD Thread()
    {
        for (;;)
        {
 
            m_rwl.Lock(true);
 
            strcpy(g_chSharedBuffer, m_pWriteData);
 
            log("W: %s", g_chSharedBuffer);
 
            Sleep((1 + rand() % 5) * 1000);
 
            log("W: try lock");
 
            m_rwl.Unlock(true);
        }
 
        return 0;
    }
};
 
int main()
{
    CReader client1;
    CWriter client2("222222222");
    CReader client3;
    CReader client4;
    CWriter client5("555");
    CReader client6;
 
    getchar();
    return 0;
}
1
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
26.05.2019, 21:08
Цитата Сообщение от Lunch Посмотреть сообщение
Синхронизация с помощью семафор(преимущество у писателей тоесть когда пишет писатель в этот момент никто из читателей не может читать )
Не пойму как даже близко реализовать подскажите пожалуйста кто может
Сделать read-write блокировку между процессами не так просто. Но выше Ygg, уже подсказал тебе вполне приемлемое решение (единственно, семафоры там нафиг не нужны)
В каждом процессе объявляешь один мьютекс на запись и с десяток на чтение
C++
1
2
HANDLE hWriteMutex = NULL;
HANDLE hReadMutex[10] = {0};
Создаёшь именованные мьютексы, CreateMutexA(....., "mutex_name"), если не получилось создать - значит уже создал кто-то другой, делаешь OpenMutex

Добавлено через 1 минуту
Имена для мьютексов - что-то типа "WriteLock", "ReadLock1"..... "ReadLock10" - во всех процессах должны быть одинаковыми

Добавлено через 3 минуты
Блокировка на запись
C++
1
2
3
4
5
6
7
8
9
10
11
12
void LockWrite
{
     ::WaitForSingleObject(hWriteMutex, INFINITE);
     ::WaitForMultipleObjects(hReadMutexes, 10, TRUE, INFINITE);
}
 
void UnlockWrite
{
for (auto &item: hReadMutexes)
     ::ReleaseMutex(item);  
::ReleaseMutex(hWriteMutex);
}
Добавлено через 4 минуты
Блокировка на чтение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
DWORD lock = 0;
void LockRead()
{
::WaitForSingleObject(hWriteMutex, INFINITE);
lock = ::WaitForMultipleObjects(hReadMutexes, 10, FALSE, INFINITE) - WAIT_OBJECT_0;
 
::ReleaseMutex(hWriteMutex);
}
 
void UnlockRead()
{
::ReleaseMutex(hReadMutexes[lock]);
 
}
1
1 / 1 / 0
Регистрация: 19.12.2017
Сообщений: 147
26.05.2019, 21:30  [ТС]
Спасибо родина вас не забудет

Добавлено через 12 секунд
Реально выручили
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.05.2019, 21:30

Семафоры. Поток не дожидается свей очереди.
#include &lt;Windows.h&gt; HDC hdc; HWND hwnd; DWORD dwWaitResult; ...

Семафоры
Здравствуйте. Как можно организовать синхронизацию двух программ, которые обращаются к одной разделяемой памяти с помощью семафоров. Мне...

Семафоры
Помогите решить задачу. Есть пример, но делаю по аналогии не получается. #include &lt;cstdlib&gt; #include &lt;iostream&gt; ...

Семафоры
Нужно написать программу &quot;Басейн&quot;. У нас есть 3 команды спортсменов. Красные , зеленые и лиловые. Каждая команда ненавидит 2 другие. ...

Семафоры
Здравствуйте. Как можно организовать синхронизацию двух программ, которые обращаются к одной разделяемой памяти с помощью семафоров. Мне...


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

Или воспользуйтесь поиском по форуму:
23
Ответ Создать тему
Новые блоги и статьи
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет) Содержание проекта Симуляция вековой (50 лет) экологической сукцессии в почве леса Основные участники: АМ-гриб, ЭКМ-гриб,. . .
сукцессия 23. Более физиологичная физиология, более экологичная экология, более диффурные диффуры.
anaschu 12.07.2026
Что реально нашли и починили за эти 5 часов Правило Линдемана (КПД конверсии сахара в тело, kEff) — раньше 100% полученного углерода шло прямо в биомассу гриба; теперь только kEff=0. 5 (после. . .
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
Сукцессия 20. Война автоботов. Делаем ставки. Лёд против "пш-пш!".
anaschu 11.07.2026
Битва ИИ в ризосфере: Как мы скрестили жесткие ОДУ, закон Фика и «подземный шантаж» Уважаемые коллеги! Хочу поделиться уникальным опытом ведения междисциплинарной компьютерной разработки. Прямо. . .
Сукцессия 19. Какие выводы я сделал из модели? Часть 2.Внутримикоризный стехиометрический буфер и хроно-дискретные зоны экспансии
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования
Сукцессия 18. Какие выводы я сделал из войны грибов с деревьями? Часть 1- рассказ и немного про термины
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования Система ОДУ описывает динамику изменения массы различных компонентов системы во времени. Ключевой. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru