Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
3 / 4 / 3
Регистрация: 23.04.2017
Сообщений: 186

Потоки

19.06.2019, 16:14. Показов 1410. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, у меня такой вопрос почему в данной проге цикл в потоках иногда срабатывает несколько раз игнорируюя WaitSingleObject?И такое происходит только иногда как это исправить?
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
#include <windows.h>
#include <iostream>
HANDLE hMutex;
int a[3] = {0,0,0};
HANDLE hThr[2];
unsigned long uThrID1;
unsigned long uThrID2;
unsigned long uThrID3;
 
void Thread(LPVOID param)
{
   int index = (int)param;
   while(1)
   {
      WaitForSingleObject(hMutex, INFINITE);
      a[index] = a[index]+index+1;
      ReleaseMutex(hMutex);
   }
}
 
int main(void)
{
   hMutex = CreateMutex(NULL, FALSE, NULL);
   hThr[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, (LPVOID)0, 0, &uThrID1);
   hThr[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, (LPVOID)1, 0, &uThrID2);
   hThr[2] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, (LPVOID)2, 0, &uThrID3);
   for (int i = 0; i < 3;i++)
   {
      WaitForSingleObject(hMutex, INFINITE);
      std::cout << a[0] << " " << a[1] << " " << a[2] << '\n';
      ReleaseMutex(hMutex);
   }
   system("pause");
   return 0;
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.06.2019, 16:14
Ответы с готовыми решениями:

Потоки
вобщем есть 3 файла с каждого считуютса даные в 4вертый (3мя потоками)как зделать чтоб они считывались по очереди сначала 2байта с 1 потом...

Потоки
Нашел пример кода. Но не пойму одну вещь. В случае, если создать поток в приостановленном состоянии, а потом его запустить, то функция,...

Потоки
Помогите создать проект Win32 с потоками, в Microsoft Visual 2010 C++. Если можно с комментариями, как и что происходит??

12
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
19.06.2019, 16:29
Цитата Сообщение от warcraft33 Посмотреть сообщение
Здравствуйте, у меня такой вопрос почему в данной проге цикл в потоках иногда срабатывает несколько раз игнорируюя WaitSingleObject?И такое происходит только иногда как это исправить?
Он его не игнорирует. Он ждёт, когда мьютекс освободится и захватывает его, потом отпускает. Всё правильно

Добавлено через 3 минуты
Цитата Сообщение от warcraft33 Посмотреть сообщение
HANDLE hThr[2];
Здесь надо HANDLE hThr[3]
0
3 / 4 / 3
Регистрация: 23.04.2017
Сообщений: 186
19.06.2019, 16:30  [ТС]
Нет если посмотреть результаты работы программы то иногда выходят артефакты например не 0 0 0 а 88 0 0, и такое колдунство срабатывает не сразу.И понять в чем причина я немогу.Т.к отладка в потоках это исскуство которым я не владею на данный момент.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
19.06.2019, 16:34
Цитата Сообщение от warcraft33 Посмотреть сообщение
Нет если посмотреть результаты работы программы то иногда выходят артефакты например не 0 0 0 а 88 0 0, и такое колдунство срабатывает не сразу.И понять в чем причина я немогу.Т.к отладка в потоках это исскуство которым я не владею на данный момент.
Это так и должно быть. У тебя бесконечный цикл, без задержек, 88 - это ещё немного

Добавлено через 58 секунд
Сделай задержку
C++
1
2
3
4
5
6
7
   while(1)
   {
      WaitForSingleObject(hMutex, INFINITE);
      a[index] = a[index]+index+1;
      ReleaseMutex(hMutex); 
      ::Sleep(100);
   }
И в main тоже

Добавлено через 46 секунд
C++
1
2
3
4
5
6
7
   for (;;)
   {
      WaitForSingleObject(hMutex, INFINITE);
      std::cout << a[0] << " " << a[1] << " " << a[2] << '\n';
      ReleaseMutex(hMutex);
      ::Sleep(100);
   }
0
3 / 4 / 3
Регистрация: 23.04.2017
Сообщений: 186
19.06.2019, 16:34  [ТС]
Фишка в том что цикл бесконечный но это пока что.В цикле должно быть ограниченное количество итераций и он должен быть контролируемым, а результаты точными
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
19.06.2019, 16:35
Цитата Сообщение от warcraft33 Посмотреть сообщение
Фишка в том что цикл бесконечный но это пока что.В цикле должно быть ограниченное количество итераций и он должен быть контролируемым, а результаты точными
В том коде, который ты показал всё сделано правильно, и работает как сделано
0
3 / 4 / 3
Регистрация: 23.04.2017
Сообщений: 186
19.06.2019, 16:36  [ТС]
А чисто на мьютексах никак не вывести?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
19.06.2019, 16:37
Цитата Сообщение от warcraft33 Посмотреть сообщение
А чисто на мьютексах никак не вывести?
На мьютексах у тебя уже сделано всё что нужно. Дальше нужны события, CreateEvent
0
3 / 4 / 3
Регистрация: 23.04.2017
Сообщений: 186
19.06.2019, 16:38  [ТС]
Кстати со Sleep так же косяки выходят.Почему происходит такой бред почему потоки не могут вовремя остановится...Может если их застопить в начале то они будут работать как надо?Как это осуществить?

Добавлено через 31 секунду
Можете пример привести?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
19.06.2019, 16:41
Цитата Сообщение от warcraft33 Посмотреть сообщение
Почему происходит такой бред почему потоки не могут вовремя остановится...
А когда они должны останавливаться?

Добавлено через 2 минуты
Я правильно понимаю, что потоки должны изменить свою переменную, потом подождать пока main напечатает все переменные?
0
3 / 4 / 3
Регистрация: 23.04.2017
Сообщений: 186
19.06.2019, 16:43  [ТС]
Да именно так)И таких перерабатываний от циклов быть не должно)
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
19.06.2019, 17:22
Лучший ответ Сообщение было отмечено warcraft33 как решение

Решение

Цитата Сообщение от warcraft33 Посмотреть сообщение
Можете пример привести?
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
static const size_t _threads = 3;
 
HANDLE hEventStop;
 
int a[_threads] = {0};
HANDLE hThreads[_threads] = {0};
HANDLE hEventCalc[_threads] = { 0 };
HANDLE hEventReady[_threads] = {0};
 
void Thread(LPVOID param)
{
    const size_t index = size_t(param);
 
    HANDLE events[2] = {hEventStop, hEventCalc[index]};
    while (::WaitForMultipleObjects(2, events, FALSE, INFINITE) == WAIT_OBJECT_0 + 1)
    {
        a[index] = a[index] + int(index) + 1;
        ::SetEvent(hEventReady[index]);
        ::Sleep(1000);
    }
}
 
int main(void)
{
    hEventStop = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
    hMutex = CreateMutex(NULL, FALSE, NULL);
    for (size_t i = 0; i < _threads; ++i)
    {
        hEventReady[i] = ::CreateEvent(nullptr, FALSE, FALSE, nullptr);
        hEventCalc[i] = ::CreateEvent(nullptr, FALSE, TRUE, nullptr);
        DWORD id;
        hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, (LPVOID)i, 0, &id);
    }
 
 
    for (;;)
    {
        ::WaitForMultipleObjects(_threads, hEventReady, TRUE, INFINITE);
        std::cout << a[0] << " " << a[1] << " " << a[2] << std::endl;
        for (size_t i = 0; i < _threads; ++i)
            ::SetEvent(hEventCalc[i]);
    }
 
    ::SetEvent(hEventStop);
    ::WaitForMultipleObjects(_threads, hThreads, TRUE, INFINITE);
    //CloseHandles
    return 0;
}
0
2734 / 889 / 331
Регистрация: 10.02.2018
Сообщений: 2,108
19.06.2019, 17:33
Цитата Сообщение от warcraft33 Посмотреть сообщение
Здравствуйте, у меня такой вопрос почему в данной проге цикл в потоках иногда срабатывает несколько раз игнорируюя WaitSingleObject?И такое происходит только иногда как это исправить?
Тут есть два момента.

Первый.
Между вызовом функции создания потока (CreateThread) и реальным запуском самого потока (Thread) есть некоторая плавающая задержка. Последовательное создание трёх потоков не означает, что все три потока запустятся одновременно на разных ядрах. Кто-то запустится раньше и он сможет выполнить несколько итераций цикла до начала работы другого потока. Если вы планируете всего три итерации в цикле, то очень велика вероятность, что первый поток выполнит все три итерации и закончит работу до того, как успеют запуститься другие потоки.

Второй.
Вы ожидаете, что WaitFor образуют очередь доступа и поток запросивший мьютекс раньше по времени получит к нему доступ первым. В общем случае это не так. Любой ожидающий поток может получить доступ первым.
Mutex Objects
If more than one thread is waiting on a mutex, a waiting thread is selected. Do not assume a first-in, first-out (FIFO) order.
Мьютекс не образует очередь запросов, если вам по условию требуется определённый порядок доступа, то вы можете организовать очередь самостоятельно на глобальных переменных. А мьютекс использовать для блокировки доступа к этой очереди.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.06.2019, 17:33
Помогаю со студенческими работами здесь

потоки
Люди,подскажите кто знает! #include&lt;windows.h&gt; #include&lt;iostream&gt; using namespace std; HANDLE hm; const int N=5; int...

Потоки
Всем привет, возникла проблема при создании потока, или не выполнении им функции, сам пока непонял))) Прошу помощи, проект нормально...

потоки
#include &quot;stdafx.h&quot; #include &lt;stdio.h&gt; #include &lt;Windows.h&gt; #include &lt;queue&gt; #include &lt;conio.h&gt; #include &lt;time.h&gt; #include...

Потоки
Здравствуйте. Начал изучать потоки и появилась необходимость передать результат работы потока в &quot;основной поток&quot;. Для этого...

Потоки
int counter=9000; DWORD WINAPI ThereadA(LPVOID p){ for (int i=0; i&lt;10000; i++) counter ++;} DWORD WINAPI ThereadB (LPVOID p) { ...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru