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

Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 40, средняя оценка - 4.73
boo_mago
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
21.03.2011, 15:51     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #1
Уважаемые программисты! Сможет ли кто-нибудь хотя бы примерно объяснить, как реализовать, например, вычисление корня квадратного уравнения, используя несколько независимых потоков. Программа должна состоять из главного потока, принимающего с клавиатуры исходные данные и выводящего на экран результат, и нескольких служебных потоков, способных по отдельности выполнять элементарные арифметические действия. Метод синхронизации - семафоры, способ передачи данных между потоками - анонимные (неименованные) каналы. Много копался в гугле, но везде все написанно достаточно трудным языком. Кто знает, в общем виде напишите пожалуйста что за чем в программе должно быть хотя бы. Спасибо вам!

Добавлено через 2 часа 48 минут
Что, никто не сталкивался? =(
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.03.2011, 15:51     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков)
Посмотрите здесь:

C++ Вычисление корней квадратного уравнения
C++ Вычисление корня квадратного из комплексного числа
Вычисление корней квадратного уравнения C++
Вычисление квадратного корня из числа C++
C++ Вычисление корня квадратного из комплексного числа
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
21.03.2011, 19:37     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #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
#include<iostream>
#include<windows.h>
#include<process.h>
 
HANDLE hReadPipe, hWritePipe, hSemaphore;
DWORD buf;
 
void f(void* p){
    int num=*reinterpret_cast<int*>(p);
    num*=2;
    if(!WriteFile(hWritePipe, &num, sizeof(num), &buf, NULL)){std::cerr<<"Error writing\n";}
    ReleaseSemaphore(hSemaphore, 1, NULL);
}
 
int main() {
    int num;
    std::cin>>num;
    if(!(hSemaphore=CreateSemaphore(NULL, 0, 1, NULL))){std::cerr<<"Create semaphore error\n"; return GetLastError();}
    if(!CreatePipe(&hReadPipe, &hWritePipe, NULL, 0)){std::cerr<<"Failed pipe creating\n"; return GetLastError();}
    _beginthread(f, 0, &num);
    while(true){
        if(WaitForSingleObject(hSemaphore, 0)==WAIT_OBJECT_0) break;
    }
    ReadFile(hReadPipe, &num, sizeof(num), &buf, NULL);
    std::cout<<num<<"\n";
}
boo_mago
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
22.03.2011, 19:04  [ТС]     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #3
Огромное спасибо за пример! Но только вот от меня требуют для потоков использовать функцию CreateThread...


И еще, нельзя ли просто написать WaitForSingleObject(hSemaphore, INFINITE)?

Добавлено через 1 час 10 минут
А что если один раз надо будет умножить на 2, а другой раз, допустим, на 3, надо создавать отдельный поток и функцию? Или это все возможно как-то сделать одним потоком в функции f?

Добавлено через 20 часов 25 минут
=((((
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
23.03.2011, 10:54     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #4
Цитата Сообщение от boo_mago Посмотреть сообщение
WaitForSingleObject(hSemaphore, INFINITE)
можно

Цитата Сообщение от boo_mago Посмотреть сообщение
один раз надо будет умножить на 2, а другой раз, допустим, на 3
все аргументы можно сложить в структуру(или массив) и передать её в функцию потока как единый аргумент

Цитата Сообщение от boo_mago Посмотреть сообщение
CreateThread
всё то же самое http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
23.03.2011, 11:18     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #5
CreateThread — это Windows-функция, создающая поток. Но никогда не вы-
зывайте ее, если Вы пишете код па C/C++. Вместо нее Вы должны использо-
вать функцию _beginthreadex из библиотеки Visual C++. (Если Вы работаете с
другим компилятором, он должен поддерживать свой эквивалент функции
CreateThread.)
Подробнее читайте у Рихтера "Windows для профессионалов...".
boo_mago
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
23.03.2011, 12:06  [ТС]     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #6
Хорошо, с CreateThread я разобрался. Еще такой вопрос, в коде СreateThread будет написано только один раз, то есть один раз надо создавать поток? Или его надо создавать каждый раз когда нужно умножить что-то?

И еще, завершать поток где-нибудь надо? ExitThread или TerminateThread...


Deviaphan, против преподователя я не попру
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
23.03.2011, 12:11     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #7
Поток завершает работу после выхода из callback функции. Т.е. создавать каждый раз.
boo_mago
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
23.03.2011, 12:24  [ТС]     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #8
А семафора одна для всего? Если у меня еще поток для сложения будет и еще что-нибудь.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
23.03.2011, 12:35     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #9
Если складываться и умножаться будут РАЗНЫЕ числа, то семафора тебе и одна не понадобится. А ждать дескриптор потока тогда.
boo_mago
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
23.03.2011, 12:58  [ТС]     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #10
Ну мне же надо при решении квадратного уравнения сначала умножать, потом результаты умножений вчитать и т.п.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
23.03.2011, 13:02     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #11
Т.е. выполнять операции последовательно. Т.е. запускать потоки последовательно. Паралельное выполнение последовательных операций не всегда реализуемо.
boo_mago
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
23.03.2011, 13:31  [ТС]     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #12
Семафора нужна тогда, когда важен предыдущий результат вычисления, т.к. он будет использоваться далее?
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
23.03.2011, 13:44     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #13
Семафора много когда нужна.
В данном случае семафор использовался для сигнализирования о завершении работы потока.
boo_mago
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
23.03.2011, 23:42  [ТС]     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #14
В общем, вот первая версия, не судите строго:
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
#include<iostream>
#include<windows.h>
#include<process.h>
#include<math.h>
 
HANDLE hReadPipe, hWritePipe, hSemaphore;
DWORD buf, as;
using namespace std;
 
struct oper
{
    int x;
    int y;
};
DWORD WINAPI um (void* p)
{
    oper arg = *reinterpret_cast<oper*>(p);
    int num = arg.x * arg.y;
    if (!WriteFile(hWritePipe, &num, sizeof(num), &buf, NULL))
    {
        cerr<<"Error writing\n";
    }
        ReleaseSemaphore(hSemaphore, 1, NULL);
    ExitThread(0);
    return 0;
} 
DWORD WINAPI plus (void* p)
{
    oper arg = *reinterpret_cast<oper*>(p);
    int num = arg.x + arg.y;
    if (!WriteFile(hWritePipe, &num, sizeof(num), &buf, NULL))
    {
        cerr<<"Error writing\n";
    }
        ReleaseSemaphore(hSemaphore, 1, NULL);
    ExitThread(0);
    return 0;
} 
DWORD WINAPI minus (void* p)
{
    oper arg = *reinterpret_cast<oper*>(p);
    int num = arg.x - arg.y;
    if (!WriteFile(hWritePipe, &num, sizeof(num), &buf, NULL))
    {
        cerr<<"Error writing\n";
    }
        ReleaseSemaphore(hSemaphore, 1, NULL);
    ExitThread(0);
    return 0;
} 
DWORD WINAPI del (void* p)
{
    oper arg = *reinterpret_cast<oper*>(p);
    int num = arg.x/arg.y;
    if (!WriteFile(hWritePipe, &num, sizeof(num), &buf, NULL))
    {
        cerr<<"Error writing\n";
    }
    ReleaseSemaphore(hSemaphore, 1, NULL);
    ExitThread(0);
    return 0;
} 
DWORD WINAPI kor (void* p)
{
    oper arg = *reinterpret_cast<oper*>(p);
    int num = sqrt((double)arg.x);
    if (!WriteFile(hWritePipe, &num, sizeof(num), &buf, NULL))
    {
        cerr<<"Error writing\n";
    }
    ReleaseSemaphore(hSemaphore, 1, NULL);
    ExitThread(0);
    return 0;
} 
int main() 
{
    int a,b,c,res2,res1,res3,x1,x2;
    cout<<"a = ";
        cin>>a;
    cout<<"b = ";
        cin>>b;
    cout<<"c = ";
        cin>>c;
    if (!(hSemaphore=CreateSemaphore(NULL, 0, 1, NULL)))
    {
        cerr<<"Create semaphore error\n"; 
        return GetLastError();
    }
    if (!CreatePipe(&hReadPipe, &hWritePipe, NULL, 0))
    {
        cerr<<"Failed pipe creating\n"; 
        return GetLastError();
    }
    oper arg; 
    ////////////////Умножаем 4 и а//////////////////////////////////////////
    arg.x = a;
    arg.y = 4;
    CreateThread(NULL, 0, um, &arg, 0, NULL);
    WaitForSingleObject(hSemaphore, INFINITE);
    ReadFile(hReadPipe, &res2, sizeof(res2), &buf, NULL);
//  cout<<"4a="<<res2<<"\n";
    ////////////////Умножаем 4а и с////////////////////////////////////////
    arg.x = res2;
    arg.y = c;
    CreateThread(NULL, 0, um, &arg, 0, NULL);
    WaitForSingleObject(hSemaphore, INFINITE);
    ReadFile(hReadPipe, &res2, sizeof(res2), &buf, NULL);
//  cout<<"4ac="<<res2<<"\n";
    ////////////////Возводим b в квадрат//////////////////////////////////
    arg.x = b;
    arg.y = b;
    CreateThread(NULL, 0, um, &arg, 0, NULL);
    WaitForSingleObject(hSemaphore, INFINITE);
    ReadFile(hReadPipe, &res1, sizeof(res1), &buf, NULL);
//  cout<<"b2="<<res1<<"\n";
    ////////////////Вычисляем дискриминант по формуле b^2 - 4ac///////////////
    arg.x = res1;
    arg.y = res2;
    CreateThread(NULL, 0, minus, &arg, 0, NULL);
    WaitForSingleObject(hSemaphore, INFINITE);
    ReadFile(hReadPipe, &res1, sizeof(res1), &buf, NULL);
//  cout<<"D="<<res1<<"\n";
    arg.x = res1;
    arg.y = 0;
    ////////////////Проверяем дискриминант////////////////////////////////////
    if (arg.x < 0)
    {
        cout<<"D<0! Net kornei!\n";
        return 1;
    }
    ////////////////Если он положительный - вычисляем корень/////////////////////
    CreateThread(NULL, 0, kor, &arg, 0, NULL);
    WaitForSingleObject(hSemaphore, INFINITE);
    ReadFile(hReadPipe, &res1, sizeof(res1), &buf, NULL);
//  cout<<"sqrt(D)="<<res1<<"\n";
    ////////////////Подсчитываем 2а////////////////////////////////////
    arg.x = a;
    arg.y = 2;
    CreateThread(NULL, 0, um, &arg, 0, NULL);
    WaitForSingleObject(hSemaphore, INFINITE);
    ReadFile(hReadPipe, &res2, sizeof(res2), &buf, NULL);
//  cout<<"2a="<<res2<<"\n";
    ////////////////Считаем -b+sqrt(D)////////////////////////////////////
    arg.x = 0 - b;
    arg.y = res1;
    CreateThread(NULL, 0, plus, &arg, 0, NULL);
    WaitForSingleObject(hSemaphore, INFINITE);
    ReadFile(hReadPipe, &res3, sizeof(res3), &buf, NULL);
//  cout<<"-b+sqrt(D)="<<res3<<"\n";
    ////////////////Считаем -b-sqrt(D)////////////////////////////////////
    CreateThread(NULL, 0, minus, &arg, 0, NULL);
    WaitForSingleObject(hSemaphore, INFINITE);
    ReadFile(hReadPipe, &res1, sizeof(res1), &buf, NULL);
//  cout<<"-b-sqrt(D)="<<res1<<"\n";
    ////////////////Считаем корни по ф-ле (-b +- sqrt(d))/2a///////////////
    arg.x = res1;
    arg.y = res2;
    CreateThread(NULL, 0, del, &arg, 0, NULL);
    WaitForSingleObject(hSemaphore, INFINITE);
    ReadFile(hReadPipe, &x1, sizeof(x1), &buf, NULL);
    cout<<"x1 = "<<x1<<"\n";
    arg.x = res3;
    arg.y = res2;
    CreateThread(NULL, 0, del, &arg, 0, NULL);
    WaitForSingleObject(hSemaphore, INFINITE);
    ReadFile(hReadPipe, &x2, sizeof(x2), &buf, NULL);
    cout<<"x2 = "<<x2<<"\n";
    CloseHandle (hReadPipe);
    CloseHandle (hWritePipe);
    CloseHandle (hSemaphore);
    return 0;
}
Добавлено через 27 минут
Вы мне уж напишите пожалуйста, если я чего лишнего понаписал, или как-то что-то не рационально использую, я ведь только учусь

Добавлено через 9 часов 8 минут
Или не напишете? =)
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
24.03.2011, 05:58     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #15
Работает - радуйся!
Не работает - не радуйся!

Для первой программы важно, чтобы работало.) А правильно и красиво придёт в будущем.)
boo_mago
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
24.03.2011, 13:06  [ТС]     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #16
Радоваться то я радуюсь =) Но хотелось бы чтобы все было по всем правилам хорошего программирования) Ибо первый раз столкнулся с семафорами/потоками/каналами, а так не первый год программирую в C++ и всегда отличался хорошим тоном.

Тем более преподавателю сдавать)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.05.2013, 15:28     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков)
Еще ссылки по теме:

Вычисление корней квадратного уравнения C++
C++ Вычисление квадратного корня из числа (без использования стандартных математических функций)
C++ Вычисление квадратного корня четных элементов массива

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

Или воспользуйтесь поиском по форуму:
StasyanKO
9 / 9 / 0
Регистрация: 13.04.2013
Сообщений: 63
29.05.2013, 15:28     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) #17
А как создавать поток в Linux компилятор GCC/G++???
Yandex
Объявления
29.05.2013, 15:28     Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков)
Ответ Создать тему
Опции темы

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