Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/33: Рейтинг темы: голосов - 33, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10

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

21.03.2011, 15:51. Показов 6893. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Уважаемые программисты! Сможет ли кто-нибудь хотя бы примерно объяснить, как реализовать, например, вычисление корня квадратного уравнения, используя несколько независимых потоков. Программа должна состоять из главного потока, принимающего с клавиатуры исходные данные и выводящего на экран результат, и нескольких служебных потоков, способных по отдельности выполнять элементарные арифметические действия. Метод синхронизации - семафоры, способ передачи данных между потоками - анонимные (неименованные) каналы. Много копался в гугле, но везде все написанно достаточно трудным языком. Кто знает, в общем виде напишите пожалуйста что за чем в программе должно быть хотя бы. Спасибо вам!

Добавлено через 2 часа 48 минут
Что, никто не сталкивался? =(
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.03.2011, 15:51
Ответы с готовыми решениями:

Вычисление корня квадратного уравнения, в общем случае
ax^2+bx+c=0 program ur; var a,b,c,d,x,x1,x2:real; begin assign(input,'input.txt'); reset(input); ...

Вычисление корней квадратного уравнения используя классы и методы
Всем привет.И сразу к сути.Нужно написать программу для вычисления корней квадратного уравнения вида ax^2+bx+c=0. Коэффициенты a,b и c...

Вычисление ряда Тейлора используя несколько потоков
Все доброго времени суток. Стоит такое задание: разработать программу вычисления соответствующего ряда Тейлора f(x)=ctg(x) в четыре потока...

16
 Аватар для igorrr37
2889 / 2036 / 992
Регистрация: 21.12.2010
Сообщений: 3,787
Записей в блоге: 9
21.03.2011, 19:37
главный поток принимает число и выводит результат, второй поток умножает его на два, передача по анонимному каналу, синхронизация семафором
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";
}
2
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
22.03.2011, 19:04  [ТС]
Огромное спасибо за пример! Но только вот от меня требуют для потоков использовать функцию CreateThread...


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

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

Добавлено через 20 часов 25 минут
=((((
0
 Аватар для igorrr37
2889 / 2036 / 992
Регистрация: 21.12.2010
Сообщений: 3,787
Записей в блоге: 9
23.03.2011, 10:54
Цитата Сообщение от boo_mago Посмотреть сообщение
WaitForSingleObject(hSemaphore, INFINITE)
можно

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

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

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


Deviaphan, против преподователя я не попру
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
23.03.2011, 12:11
Поток завершает работу после выхода из callback функции. Т.е. создавать каждый раз.
0
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
23.03.2011, 12:24  [ТС]
А семафора одна для всего? Если у меня еще поток для сложения будет и еще что-нибудь.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
23.03.2011, 12:35
Если складываться и умножаться будут РАЗНЫЕ числа, то семафора тебе и одна не понадобится. А ждать дескриптор потока тогда.
0
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
23.03.2011, 12:58  [ТС]
Ну мне же надо при решении квадратного уравнения сначала умножать, потом результаты умножений вчитать и т.п.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
23.03.2011, 13:02
Т.е. выполнять операции последовательно. Т.е. запускать потоки последовательно. Паралельное выполнение последовательных операций не всегда реализуемо.
0
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
23.03.2011, 13:31  [ТС]
Семафора нужна тогда, когда важен предыдущий результат вычисления, т.к. он будет использоваться далее?
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
23.03.2011, 13:44
Семафора много когда нужна.
В данном случае семафор использовался для сигнализирования о завершении работы потока.
0
0 / 0 / 0
Регистрация: 20.09.2010
Сообщений: 10
23.03.2011, 23:42  [ТС]
В общем, вот первая версия, не судите строго:
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 минут
Или не напишете? =)
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
24.03.2011, 05:58
Работает - радуйся!
Не работает - не радуйся!

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

Тем более преподавателю сдавать)
0
9 / 9 / 0
Регистрация: 13.04.2013
Сообщений: 63
29.05.2013, 15:28
А как создавать поток в Linux компилятор GCC/G++???
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.05.2013, 15:28
Помогаю со студенческими работами здесь

Вычисление квадратного корня
я уже смотрел на форуме, какой у квадратного корня алгоритм. В основу моего алгоритма тоже положен метод касательных. Но! У моего...

Вычисление квадратного корня
Всем привет:) Прошу помощи в составлении программы по вычислению квадратного корня из конечного числа.. Сначала ввожу значение Re=.. и...

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

Вычисление квадратного корня
Нужен алгоритм быстрого вычисления квадратного корня. Прошу поделиться примерами, ссылками. Сам ни разу не математик. Для AVR. Си....

Вычисление квадратного корня
Доброе время суток форумчани, я не как не могу разобраться как найти ошибку корня, вот такая задача у меня есть уравнение...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
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. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru