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

Мьютексы - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 66, средняя оценка - 5.00
ganjawar
0 / 0 / 0
Регистрация: 09.09.2011
Сообщений: 40
03.11.2011, 15:10     Мьютексы #1
Здравствуйте..
У Меня задача синхронизовать потоки,которые "делят "между собой какой-нибудь ресурс.
Допустим проходят массив от 0 -10.
то есть есть рандомная очередь из 2-х потоков..например 121122 где 1 -это первый поток а 2-второй соответственно..
и пока 1 поток проходит по массиву второй ждет..потом второй проходит а первый ждет..и так проходит вся очередь..до самой задачи мне далеко.. не пойму как синхронизовать мьютексом эти 2 потока
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
#include <Windows.h>
#include <iostream>
#include <process.h>
using namespace std;
 
char mass[10];
DWORD ThreadId;
HANDLE hMutex;
DWORD dwWaitResult;
void left_to();//переход справа налево
void right_to();//переход слева направо
bool write_way(int way);
int queue[5];
 
int main()
{
    int res=0;
    bool move;
    hMutex = CreateMutex( NULL, FALSE, NULL);
    int i=0;
    for(i=0;i<=4;i++)
    {
        int a = rand() % 10;//выбираем рандомно в какую сторону начнется движение
        queue[i]=a;
    }
    move = write_way(queue[i]);
 
        /*if(queue[i]==1)//если =1 то допускаем движение влево
        {
            
            HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)left_to, 0, 0, &ThreadId);
        }else if (queue[i]==2)
        {   //иначе движение вправо
            HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)right_to, 0, 0, &ThreadId);
        }*/
    return 1;
}
 
bool write_way(int way)
{
    dwWaitResult = WaitForSingleObject( hMutex, 5000L);
    if (dwWaitResult == WAIT_TIMEOUT) // Таймаут. Мьютекс за это время не освободился.
    {
        return 0;
    }
    else // Мьютекс освободился, и наш поток его занял. Можно работать.
    {
        if (way==1)
        {
            HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)left_to, 0, 0, &ThreadId);
        }else if (way==2)
        {
            HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)right_to, 0, 0, &ThreadId);
        }
        ReleaseMutex(hMutex); // Освобождаем мьютекс.
    }
}
void left_to()
{
 
}
void right_to()
{
 
}
Буду рад если предложите свою идею насчет ресурса который делят..
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.11.2011, 15:10     Мьютексы
Посмотрите здесь:

Мьютексы C++ Builder
C++ Мьютексы, семафоры
C++ Объекты синхронизации. мьютексы, семафоры
Delphi Мьютексы
Мьютексы C++ WinAPI
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Mustik
56 / 56 / 2
Регистрация: 10.07.2011
Сообщений: 229
03.11.2011, 16:39     Мьютексы #2
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
void left_to()
{
        while(1)
        {
                dwWaitResult = WaitForSingleObject( hMutex, 5000L);
                if (dwWaitResult == WAIT_TIMEOUT) // Таймаут. Мьютекс за это время не освободился.
                {
                        return 0;
                }
                /* ЧТО ХОТИМ ТО И ДЕЛАЕМ C МАССИВОМ */
                ReleaseMutex(hMutex); // Освобождаем мьютекс.
                if( /* Условие завершения потока */)
                        return 1;
        }
}
void right_to()
{
        while(1)
        {
                dwWaitResult = WaitForSingleObject( hMutex, 5000L);
                if (dwWaitResult == WAIT_TIMEOUT) // Таймаут. Мьютекс за это время не освободился.
                {
                        return 0;
                }
                /* ЧТО ХОТИМ ТО И ДЕЛАЕМ С МАССИВОМ*/
                ReleaseMutex(hMutex); // Освобождаем мьютекс.
                if( /* Условие завершения потока */)
                        return 1;
        } 
}
А из bool write_way(int way) убери dwWaitResult = WaitForSingleObject( hMutex, 5000L); и ReleaseMutex(hMutex);
До освобождения мьютекса WaitForSingleObject( hMutex, 5000L) не пустит поток к /* ЧТО ХОТИМ ТО И ДЕЛАЕМ С МАССИВОМ*/
ganjawar
0 / 0 / 0
Регистрация: 09.09.2011
Сообщений: 40
03.11.2011, 16:47  [ТС]     Мьютексы #3
то есть как Я понял проверить и занимать мьютекс нужно непосредственно в том потоке который мы вызываем?
а сам потом можно создавать прямо из main првильно?
Mustik
56 / 56 / 2
Регистрация: 10.07.2011
Сообщений: 229
03.11.2011, 17:02     Мьютексы #4
Цитата Сообщение от ganjawar Посмотреть сообщение
то есть как Я понял проверить и занимать мьютекс нужно непосредственно в том потоке который мы вызываем?
Функция WaitForSingleObject как бы сдерживает поток на себе пока не освободится мьютекс, ну или в течение 5 секунд, а в это время, второй поток выполняет то, что вы хотите.
Цитата Сообщение от ganjawar Посмотреть сообщение
а сам потоК можно создавать прямо из main првильно?
ну если вы про поток, то - Да. Кто-то где-то писал, что после закрытия потока нужно еще и созданные хэндлы закрывать, ну или что-то типо того.

Я допустил ошибку, в потоках исправьте return 1 и return 0 на return, т.к. функция void.
Да и, мне кажется, что ваши функции должны выглядеть как-нить
C++
1
void right_to(LPVOID ThreadParams)
Не работал никогда с CreateThread, но вот создание потоков через _beginthread явно ругается, если нету в параметрах функции потока указателя.
ganjawar
0 / 0 / 0
Регистрация: 09.09.2011
Сообщений: 40
03.11.2011, 23:04  [ТС]     Мьютексы #5
то что функция сдерживает поток это Я понял
а как мьютекс цепляется к потоку?
он же вроде отдельно создается..да и поток отдельно
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
03.11.2011, 23:36     Мьютексы #6
ganjawar, мьютекс — это, грубо говоря, глобальная по отношению к данной области видимости переменная. Он никак не цепляется к потоку. Просто когда один поток блокирует мьютекс, другие уже не могут его заблокировать, и ждут, пока первый его разблокирует.
Получается, что область программы, расположенная между блокировкой и разблокировкой мьютекса — это такая зона, которую в каждый промежуток времени может исполнять только один поток.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.11.2011, 09:53     Мьютексы
Еще ссылки по теме:

Понятие синхронизации потоков и процессов. Семафоры и мьютексы C++
мьютексы
SQLite и мьютексы C++ Qt

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

Или воспользуйтесь поиском по форуму:
Mustik
56 / 56 / 2
Регистрация: 10.07.2011
Сообщений: 229
04.11.2011, 09:53     Мьютексы #7
Задача мьютекса — защита объекта от доступа к нему других потоков, отличных от того, который завладел мьютексом. В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом. Если другому потоку будет нужен доступ к переменной, защищённой мьютексом, то этот поток засыпает до тех пор, пока мьютекс не будет освобождён. (c) Википедия

Есть еще вариант с критическими секциями. Принцип тот же.
Создаем критическую секцию
C++
1
CRITICAL_SECTION cs;
глобально, в main инициализируем
C++
1
InitializeCriticalSection( &cs );
, а в потоках, вместо WaitForSingleObject
C++
1
EnterCriticalSection( &cs );
, а вместо ReleaseMutex
C++
1
LeaveCriticalSection( &cs );
Вот понятная, вроде, ссылка
Yandex
Объявления
04.11.2011, 09:53     Мьютексы
Ответ Создать тему
Опции темы

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