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

Two Threads + CriticalSection - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ головоломка для знающих... http://www.cyberforum.ru/cpp-beginners/thread333058.html
Описать функцию Ln1(x, ) вещественного типа (параметры x,  — вещественные, |x| < 1,  > 0), находящую приближенное значение функции ln(1 + x): ln(1 + x) = x – x2/2 + x3/3 – … + (–1)n•xn+1/(n+1) + … . В сумме учитывать все слагаемые, модуль которых больше . С помощью Ln1 найти приближенное значение ln(1 + x) для данного x при шести данных . :scratch:
C++ Значения матрицы найти 2 наибольших значения из четных столбцов и их индексы записать функцией http://www.cyberforum.ru/cpp-beginners/thread333026.html
C++ Получить из кода символ
Нужно как-то перегнать код символа (по таблице ASCII символов) в символ. Как это можно сделать? Допустим у меня есть строка string str1. Я хочу получить записать в неё символ с кодом 65, как это сделать? Вариант "запиши туда букву A и всё" не подойдёт так как программа будет писать символы по кодам и я заранее не знаю какой код будет, весь алфавит case'ом пробегать будет по быдлокодерски же....
C++ Различные приемы работы с матрицами - готовое решение
подрихтовал для матриц и массивов 2 с лишним часа жизни >_< #include <iostream> #include <time.h> using std::cout; using std::endl; using std::cin; void matrPrint ( int **, int, int ); void matrSortUp ( int **, int, int );
C++ Ответ на упражнение, которое я задал в другой теме про перевод диагональных координат в стандартные http://www.cyberforum.ru/cpp-beginners/thread332999.html
Всё просто довольно. Как и обещал, две строки. Чтобы не говорили, что я типа в кустах struct koordinati_ { int nomer_stroki; int nomer_stolbtsa; koordinati_ }; template <class T> bool matrix<T>::f_perevod_koordinat (koordinati_* koordinati, int y, int x) { koordinati->nomer_stroki= y- ((y- kol_vo_strok+ 1)+ abs(y- kol_vo_strok+ 1))/2- x;
C++ Вставить в строку s содержимое s1 начиная с позиции n Помогите пожалуйста написать программу! Вставить в строку s содержимое s1 начиная с позиции n. То есть сначала идут n-первых символов s, тогда символы s1, а дальше-те символы, которые были у s до вставки s1, начиная с позиции n. Это нужно сделать не используя библиотеки <string.h>, а создать собственную функцию Insert (s, s1, n) ... Заранее спасибо! подробнее

Показать сообщение отдельно
goto
 Аватар для goto
76 / 34 / 4
Регистрация: 04.04.2011
Сообщений: 78
Записей в блоге: 1
14.07.2011, 23:16  [ТС]     Two Threads + CriticalSection
лучше использовать mutex-ы они быстрее работают
у меня почему-то с точность да наоборот... причем разница в разы! (если брать одно и тоже время работы и смотреть на значения GlobalData, вариант с секций в разы быстрее) это я думаю объясняется тем что мютекс, - уровень ядра винды - отсюда тормоза, а секция локальная фича процесса, и ядро не задействуется либо если и юзается то в особом случае. По крайней мере из моих ковыряний я сделал именно такие выводы.

добавил культурное само убийство потока... по глобальному флагу... с новой крит. секцией для флага.
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
#include <stdio.h>
#include <stdlib.h>
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0500
#include <windows.h>
 
DWORD ThreadTwoId = 0;
HANDLE ThreadTwoHandle = 0;
 
CRITICAL_SECTION GlobalDataCriticalSection;
float GlobalData[10] = {0,0,0,0,0,0,0,0,0,0};
 
CRITICAL_SECTION GlobalTerminateCriticalSection;
bool GlobalTerminate = false;
 
DWORD ThreadTwo(LPVOID lpdwThreadParam) 
{
    bool run = true;
 
    while(run) 
    {
        EnterCriticalSection(&GlobalDataCriticalSection);
        // Потоку удалось получить доступ, изменим данные
        for (int i = 0; i < 5; i++)
        {
            GlobalData[i]+=0.00001f;
        };
        LeaveCriticalSection(&GlobalDataCriticalSection);
 
        // Посмотрим вдруг потоку надо убить-ся?
        EnterCriticalSection(&GlobalTerminateCriticalSection);
        if ( GlobalTerminate ) run = false;
        LeaveCriticalSection(&GlobalTerminateCriticalSection);
 
        //Sleep(1);
    }
    return EXIT_SUCCESS;
}
 
 
int main () 
{
    DWORD dwWaitResult = 0;
 
    InitializeCriticalSection(&GlobalDataCriticalSection);
    InitializeCriticalSection(&GlobalTerminateCriticalSection);
    
 
    ThreadTwoHandle = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE) &ThreadTwo, 0, 0, &ThreadTwoId );
 
    while(1) 
    {           
        EnterCriticalSection(&GlobalDataCriticalSection);
        // Потоку удалось получить доступ, изменим данные
        for (int i = 5; i < 10; i++)
        {
            GlobalData[i]-=0.00001f;
        };
        LeaveCriticalSection(&GlobalDataCriticalSection);
 
        if (GetAsyncKeyState(VK_ESCAPE) & 0x8000 ) 
        {
            EnterCriticalSection(&GlobalTerminateCriticalSection);
            GlobalTerminate = true;
            LeaveCriticalSection(&GlobalTerminateCriticalSection);
            break;
        }
        //Sleep(1);
    }
 
    // Ждем пока скончается второй поток... долго ждем
    WaitForSingleObject(ThreadTwoHandle, INFINITE);
    //SuspendThread(ThreadTwoHandle);
    
    // Завершение программы
    CloseHandle(ThreadTwoHandle);
    DeleteCriticalSection(&GlobalDataCriticalSection);
 
 
    // Выводим результат работы потоков
    printf("\n GlobalData \n { ");
    for (int i = 0; i < 10; i++)
    {
        printf(" %f ", GlobalData[i]);
    }
    printf(" }\n");
 
    getchar();
    return EXIT_SUCCESS;
}
Добавлено через 46 минут
вариант с мютексами
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
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
 
DWORD ThreadTwoId = 0;
HANDLE ThreadTwoHandle = 0;
 
HANDLE GlobalDataMutex = 0;
float GlobalData[10] = {0,0,0,0,0,0,0,0,0,0};
 
HANDLE GlobalTerminateMutex = 0;
bool GlobalTerminate = false;
 
 
 
DWORD ThreadTwo(LPVOID lpdwThreadParam) 
{
    DWORD dwWaitResult = 0; 
    bool run = true;
 
    while(run) 
    {
        
        // первый мютекс для глобального флага GlobalTerminate
        if  (WAIT_OBJECT_0 == (dwWaitResult = WaitForSingleObject(GlobalTerminateMutex, 0))) 
        {
            // Убиться потоку?
            if (GlobalTerminate) run = false;
            ReleaseMutex(GlobalTerminateMutex);
        }
 
        
        // второй мютекс для данных разделяемых обоими потоками... 
        // в некоторый момент времени только один имеет к нему доступ
        dwWaitResult = WaitForSingleObject(GlobalDataMutex, 0);
 
        switch(dwWaitResult) 
        {
        case WAIT_OBJECT_0:
            {
                // Потоку удалось получить доступ, изменим данные
                for (int i = 0; i < 5; i++)
                {
                    GlobalData[i]+=0.00001;
                }
                // Освободим для другого потока
                ReleaseMutex(GlobalDataMutex); 
            
                break;
            }
        case WAIT_ABANDONED:
            // Потоку не удалось получить доступ
            
            break;
 
        }   
    }
 
    return EXIT_SUCCESS;
}
 
 
int main () 
{
    DWORD dwWaitResult = 0;
 
    ThreadTwoHandle = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE) &ThreadTwo, 0, 0, &ThreadTwoId );
 
    GlobalDataMutex = CreateMutex(NULL, FALSE, NULL);
    GlobalTerminateMutex = CreateMutex(NULL, FALSE, NULL);
 
 
    while(1) 
    {
        
        dwWaitResult = WaitForSingleObject(GlobalDataMutex, 0);
 
        switch(dwWaitResult) 
        {
        case WAIT_OBJECT_0:
            {
                // Потоку удалось получить доступ, изменим данные
                for (int i = 5; i < 10; i++)
                {
                    GlobalData[i]-=0.00001;
                }
                // Освободим для другого потока
                ReleaseMutex(GlobalDataMutex);             
                break;
            }
        case WAIT_ABANDONED:
            // Потоку не удалось получить доступ            
            break;
        }
        //Sleep(1);
 
        if (GetAsyncKeyState(VK_ESCAPE) & 0x8000 ) //выходи по нажанию Esc
        { 
            // Ждем освобождения GlobalTerminateMutex ...вечно ждем... 
            if  (WAIT_OBJECT_0 == (dwWaitResult = WaitForSingleObject(GlobalTerminateMutex, INFINITE))) 
            {
                // Изменим
                GlobalTerminate = true;
                // Переключим мютекс в свободный... другой поток может опрашивать GlobalTerminate
                ReleaseMutex(GlobalTerminateMutex);
            }
 
            break; // выходим из While(1)
        }
    }
 
    // Завершение программы
    // Второй поток закончится пойдем ниже
    WaitForSingleObject(ThreadTwoHandle, INFINITE);
 
    // закрываем мютексы
    CloseHandle(GlobalDataMutex);
    CloseHandle(GlobalTerminateMutex);
    // закрываем поток
    CloseHandle(ThreadTwoHandle);
 
    // Выводим результат работы потоков
    printf("\n GlobalData \n { ");
    for (int i = 0; i < 10; i++)
    {
        printf(" %.2f ", GlobalData[i]);
    }
    printf(" }\n");
 
    getchar();
    return EXIT_SUCCESS;
}
вопрос. насколько уместно оборачивать мелкие переменные в мютексы/крит секции? если допустим мне понадобиться 20 разных переменных которые разделяют потоки, мне что каждую из них оборачивать в вывоз мютекса или EnterCriticalSection/LeaveCriticalSection ? Либо же атомарные не динамические данные никто не оборачивает, а юзают что назыв. в лоб?
 
Текущее время: 11:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru