Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++: WinAPI
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
auditseo
56 / 56 / 2
Регистрация: 10.03.2014
Сообщений: 73
1

Синхронизация потоков

22.04.2015, 19:50. Просмотров 908. Ответов 1
Метки нет (Все метки)

Нужно:
Выполнение нескольких арифметических операций разного приоритета.
Оперировать с помощью мьютексов и кретических секций, как лучше реализовать?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.04.2015, 19:50
Ответы с готовыми решениями:

Синхронизация потоков
Здравствуйте. Подскажите пожалуйста. У меня есть три потока. Мне нужно чтобы...

Синхронизация потоков
Здравствуйте, уважаемые форумчане! Нужно мне написать прогу на синхронизацию....

Синхронизация потоков
Помогите обеспечить синхронизацию потоков const int j=20; hSemaphore =...

Синхронизация потоков
Помогите синхронизировать два потока на Win32 Api. 1й выводит числовую...

Синхронизация потоков
в общем есть код: DWORD WINAPI...

1
auditseo
56 / 56 / 2
Регистрация: 10.03.2014
Сообщений: 73
24.04.2015, 20:59  [ТС] 2
Лучший ответ Сообщение было отмечено auditseo как решение

Решение

Выложу код, возможно, кому-то пригодится.

Сделал такой простой пример с помощью мьютекса:

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
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
HANDLE hMutex;
 
void ThreadPlus(char expression[50][10])
{
    WaitForSingleObject(hMutex, INFINITE);
    for (int i = 0; expression[i][0] != '\0'; i++){
        if (!strcmp(expression[i], "+") || !strcmp(expression[i], "-")){
    std::cout << "\nНашли + или - ---> expression[i] = " << expression[i] << "\n";
            int tempNumber;
            if (!strcmp(expression[i], "+")){
            tempNumber = atoi(expression[i - 1]) + atoi(expression[i + 1]);
            }
            else if (!strcmp(expression[i], "-")){
            tempNumber = atoi(expression[i - 1]) - atoi(expression[i + 1]);
            }
            //копируем результат вычисления в ячейку i - 1
            _itoa_s(tempNumber, expression[i - 1], 10);
            //смешение всех знаков или чисел на два знака влево
            int j;
            for (j = i; expression[j + 2][0] != '\0'; j++){
                strcpy_s(expression[j], expression[j + 2]);
            }
            strcpy_s(expression[j], "");
            strcpy_s(expression[j + 1], "");
            std::cout << "\nВывод-промежуточно\n";
            for (int i = 0; expression[i][0] != '\0'; i++){
                std::cout << expression[i];
            }
            //откатываемся назад для проверки
            i--;
        }
 
    }
    ReleaseMutex(hMutex);
}
void ThreadMultiply(char expression[50][10])
{
    WaitForSingleObject(hMutex, INFINITE);
    for (int i = 0; expression[i][0] != '\0'; i++){
        if (!strcmp(expression[i], "*") || !strcmp(expression[i], "/")){
    std::cout << "\nНашли * или / ---> expression[i] = " << expression[i] << "\n";
            int tempNumber;
            if (!strcmp(expression[i], "*")){
            tempNumber = atoi(expression[i - 1]) * atoi(expression[i + 1]);
            }
            else if (!strcmp(expression[i], "/")){
            tempNumber = atoi(expression[i - 1]) / atoi(expression[i + 1]);
            }
            
            _itoa_s(tempNumber, expression[i - 1], 10);
            //смешение всех знаков или чисел на два знака влево
            int j;
            for (j = i; expression[j + 2][0] != '\0'; j++){
                strcpy_s(expression[j], expression[j + 2]);
            }
            strcpy_s(expression[j], "");
            strcpy_s(expression[j + 1], "");
            std::cout << "\nВывод-промежуточно\n";
            for (int i = 0; expression[i][0] != '\0'; i++){
                std::cout << expression[i];
            }
            //откатываемся назад для проверки
            i--;
        }
        Sleep(100);     //Показать, что МЬЮТЕКС РАБОТАЕТ
    }
    ReleaseMutex(hMutex);
}
 
int main(void)
{
#pragma warning(disable : 4996)
    setlocale(LC_ALL, "Russian");
    system("color f0");
    //тестовый массив
char expression[50][10] = { "100", "+", "22", "+", "9", "+", "10", "*", "3", "*", "2", "+", "3", "-", "10", "/", "5" };
    std::cout << "Initinal expression:\n\n";
    for (int i = 0; expression[i][0] != '\0'; i++){
        std::cout << expression[i];
    }
    std::cout << "\n";
    HANDLE hThrPlus;
    HANDLE hThrMultiply;
    const int COUNT_THREAD = 2;
    HANDLE arrayHandleThread[COUNT_THREAD];
    unsigned long uThrPlusID;
    unsigned long uThrMultiplyID;
    hMutex = CreateMutex(NULL, FALSE, NULL);    
    hThrMultiply = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadMultiply, expression, 0, &uThrMultiplyID);
    if (hThrMultiply != NULL){
        std::cout << "\n1-ый поток создался\n";
hThrPlus = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadPlus, expression, 0, &uThrPlusID);
        if (hThrPlus){
            std::cout << "\n2-ой поток создался\n";
        }
        else{
            std::cout << "\n2-ой поток не удалось создать\n";
        }
    }
    else{
    std::cout << "\n1-ый поток не удалось создать! Поэтому не будем создавать 2-ой!";
    }
//заносим в массив дескрипторов, чтобы отследить, когда потоки завершат свою работу
    arrayHandleThread[0] = hThrMultiply;
    arrayHandleThread[1] = hThrPlus;
    //ждем когда потоки завершат свою работу
    WaitForMultipleObjects(COUNT_THREAD, arrayHandleThread, TRUE, INFINITE);
    std::cout << "\n______________Вывод_______________\n";
    for (int i = 0; expression[i][0] != '\0'; i++){
 
        std::cout << expression[i];
    }
    //закрываем потоки
    CloseHandle(hThrMultiply);
    CloseHandle(hThrPlus);
    CloseHandle(hMutex);
    std::cout << "\n";  
    system("pause");
    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
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
HANDLE hEvent;
 
void ThreadPlus(char expression[50][10])
{
    WaitForSingleObject(hEvent, INFINITE);
    //устанавливаем в значение занято
    ResetEvent(hEvent);
    for (int i = 0; expression[i][0] != '\0'; i++){
        if (!strcmp(expression[i], "+") || !strcmp(expression[i], "-")){
    std::cout << "\nНашли + или - ---> expression[i] = " << expression[i] << "\n";
            int tempNumber;
            if (!strcmp(expression[i], "+")){
            tempNumber = atoi(expression[i - 1]) + atoi(expression[i + 1]);
            }
            else if (!strcmp(expression[i], "-")){
            tempNumber = atoi(expression[i - 1]) - atoi(expression[i + 1]);
            }
            //копируем результат вычисления в ячейку i - 1
            _itoa_s(tempNumber, expression[i - 1], 10);
            //смешение всех знаков или чисел на два знака влево
            int j;
            for (j = i; expression[j + 2][0] != '\0'; j++){
                strcpy_s(expression[j], expression[j + 2]);
            }
            strcpy_s(expression[j], "");
            strcpy_s(expression[j + 1], "");
            std::cout << "\nВывод-промежуточно\n";
            for (int i = 0; expression[i][0] != '\0'; i++){
                std::cout << expression[i];
            }
            //откатываемся назад для проверки
            i--;
        }
 
    }
    SetEvent(hEvent);   //переводим в положение свободно
}
 
void ThreadMultiply(char expression[50][10])
{
    WaitForSingleObject(hEvent, INFINITE);
    //устанавливаем в значение занято
    ResetEvent(hEvent);
    for (int i = 0; expression[i][0] != '\0'; i++){
        if (!strcmp(expression[i], "*") || !strcmp(expression[i], "/")){
            std::cout << "\nНашли * или / ---> expression[i] = " << expression[i] << "\n";
            int tempNumber;
            if (!strcmp(expression[i], "*")){
            tempNumber = atoi(expression[i - 1]) * atoi(expression[i + 1]);
            }
            else if (!strcmp(expression[i], "/")){
            tempNumber = atoi(expression[i - 1]) / atoi(expression[i + 1]);
            }
            _itoa_s(tempNumber, expression[i - 1], 10);
            //смешение всех знаков или чисел на два знака влево
            int j;
            for (j = i; expression[j + 2][0] != '\0'; j++){
                strcpy_s(expression[j], expression[j + 2]);
            }
            strcpy_s(expression[j], "");
            strcpy_s(expression[j + 1], "");
            std::cout << "\nВывод-промежуточно\n";
            for (int i = 0; expression[i][0] != '\0'; i++){
                std::cout << expression[i];
            }
            //откатываемся назад для проверки
            i--;
        }
        Sleep(100);     //Показать, что МЬЮТЕКС РАБОТАЕТ (поток спит, но не передает управлнеие другому)
    }
    SetEvent(hEvent);   //переводим в положение свободно
}
 
int main(void)
{
#pragma warning(disable : 4996)
    setlocale(LC_ALL, "Russian");
    system("color f0");
    //тестовый массив
    char expression[50][10] = { "100", "+", "22", "+", "9", "+", "10", "*", "3", "*", "2", "+", "3", "-", "10", "/", "5" };
    std::cout << "Initinal expression:\n\n";
    for (int i = 0; expression[i][0] != '\0'; i++){
        std::cout << expression[i];
    }
    std::cout << "\n";
    HANDLE hThrPlus;
    HANDLE hThrMultiply;
    const int COUNT_THREAD = 2;
    HANDLE arrayHandleThread[COUNT_THREAD];
    unsigned long uThrPlusID;
    unsigned long uThrMultiplyID;
 
    hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);      //2-ой параметр - указывает, что автосброс; 3-ий - что событие свободно
    hThrMultiply = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadMultiply, expression, 0, &uThrMultiplyID);
    if (hThrMultiply != NULL){
        std::cout << "\n1-ый поток создался\n";
        hThrPlus = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadPlus, expression, 0, &uThrPlusID);
        if (hThrPlus){
            std::cout << "\n2-ой поток создался\n";
        }
        else{
            std::cout << "\n2-ой поток не удалось создать\n";
        }
    }
    else{
    std::cout << "\n1-ый поток не удалось создать! Поэтому не будем создавать 2-ой!";
    }
    //заносим в массив дескрипторов, чтобы отследить, когда потоки завершат свою работу
    arrayHandleThread[0] = hThrMultiply;
    arrayHandleThread[1] = hThrPlus;
    //ждем когда потоки завершат свою работу
    WaitForMultipleObjects(COUNT_THREAD, arrayHandleThread, TRUE, INFINITE);
    std::cout << "\n______________Вывод_______________\n";
    for (int i = 0; expression[i][0] != '\0'; i++){
 
        std::cout << expression[i];
    }
    //закрываем потоки
    CloseHandle(hThrMultiply);
    CloseHandle(hThrPlus);
    CloseHandle(hEvent);
    std::cout << "\n";
    system("pause");
    return 0;
}
Когда я создаю два потока:

hThrMultiply = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadMultiply, expression, 0, &uThrMultiplyID);

hThrPlus = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadPlus, expression, 0, &uThrPlusID);
Как указать, чтобы hThrMultiply запустился ПЕРВЫМ?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.04.2015, 20:59

Синхронизация потоков
Вот код: #include &quot;iostream&quot; #include &quot;windows.h&quot; using namespace std; ...

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

Синхронизация потоков
Как переделать с использованием mutex или еще чего нибудь? /*Три нити....


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

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru