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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.67
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 269
#1

Потоки. Основа. - C++

11.03.2012, 18:53. Просмотров 1570. Ответов 23
Метки нет (Все метки)

Помогите разобраться с потоками WinAPI.
Нужны только азы.
Для начала создание, уничтожение, передача параметров
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "stdafx.h"
#include <WinBase.h>
 
 
DWORD WINAPI func(PVOID param)
{
 
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    CreateTread(NULL, 0, func, param, 0);
    
    return 0;
}
1.) у CreateTread тип возвращаемого значения - HANDLE. Это что-то типо адреса потока? Где его запоминать?
2.) PVOID и LPVOID. Нашёл, что LPVOID отличается от PVOID тем, что он "far". Как мне помнится, это слово влияет на возможноть расположение в области памяти, отличной от главного потока.
3.) главный поток - это инт тмейн? или нужно начать программу по-другому?
4.) то, что на писано, не компилируется. Выдаётся много ошибок типа:
C++
1
2
3
4
5
6
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winbase.h(300): error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "wMinute"
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winbase.h(300): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winbase.h(300): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winbase.h(301): error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "wSecond"
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winbase.h(301): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winbase.h(301): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
5.) Передача параметров. Скажем, я хочу передать в функцию два иттератора. Непонятен сам процесс передачи параметров...что мне следует делать? Загонять оба иттератора в структуру?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.03.2012, 18:53     Потоки. Основа.
Посмотрите здесь:

В равнобедренном треугольнике известна основа с и угол при ней - C++
В равнобедренном треугольнике известна основа с и угол при ней. Найти площадь треугольника S и величину боковой стороны а.

потоки - C++
1---------------------------------------------------------------------------------------------------------- Можно ли перенаправить потоки...

Потоки - C++
Пытаюсь создать поток #include&lt;windows.h&gt; #include&lt;iostream&gt; #include &lt;stdio.h&gt; #include &lt;process.h&gt; #include &lt;fstream&gt; using...

Потоки - C++
Есть некоторая консольная программа. Необходимо обернуть ее в гуи, то есть самого консольного окна быть не должно. Как я понял это проще...

Потоки - C++
Всем привет! Делаю тут одну программу(консольную игру), возникла надабность запустить одну и туже функцию в паралельных потоках, т. е....

потоки - C++
как с помошью потоков считать из файла два числа K и N: ifstream input(&quot;input.txt&quot;,ifstream::binary); int K,N;

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 19:09     Потоки. Основа. #2
1) Хендл потока, своеобразный идентификатор. Нужен, чтобы потом у этому потоку можно было обращаться
2) far это макрос который ничему не равен. В Windows нет длинных и коротких указателей. Только один на всех.
3) int main() - примерно так, первый код, запускаемый в первичном потоке, исключая глобальные переменные, которые равны значениям функций и прочую лабуду. Если приложение оконное, то вместо int main() WinMain
4) надо подключать windows.h, а не winbase.h
5) загонять в структуру

Добавлено через 41 секунду
С итераторами вообще аккуратней. Они потокозависимы.
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 269
11.03.2012, 19:30  [ТС]     Потоки. Основа. #3
Так, уже лучше)
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
#include "stdafx.h"
#include <Windows.h>
#include <vector>
#include <iostream>
using namespace std;
 
template <typename T>
struct para
{
    T begin,end;
    para (T b, T e)
    {
        begin = b;
        end = e;
    }
};
 
DWORD WINAPI func(PVOID param)
{
 
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    para<vector<int>::iterator> p(b.begin(), b.end());
 
    CreateThread(NULL, 0, func, p, 0);
    
    return 0;
}
1.) Как же всё-таки передать мою пару иттераторов в func?
2.) Где можно хранить хендл потока? Если я создам
C++
1
HANDLE potok[10]
там можно?
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 19:42     Потоки. Основа. #4
1)
не понятно, что такое b, но не суть.
C++
1
2
para<vector<int>::iterator> p(b.begin(), b.end());
CreateThread(NULL, 0, func, (LPVOID)&p, 0);
C++
1
2
3
4
DWORD WINAPI func(PVOID param)
{
 para<vector<int>::iterator> *p = (para<vector<int>::iterator>*) param;
}
2) Хранить можно где угодно. Главное, что бы был доступ.
retmas
Жарю без масла
859 / 741 / 164
Регистрация: 13.01.2012
Сообщений: 1,694
11.03.2012, 19:43     Потоки. Основа. #5
Цитата Сообщение от IcyWind Посмотреть сообщение
1.) Как же всё-таки передать мою пару иттераторов в func?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef para<vector<int>::iterator> iterator_pair;
 
DWORD WINAPI func(PVOID param)
{
    iterator_pair p = *static_cast<iterator_pair*>(param);
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    iterator_pair p(b.begin(), b.end());
 
    CreateThread(NULL, 0, func, &p, 0);
        
    return 0;
}
но берегитесь. в передаче итераторов - целый букет подводных камней. шаг в сторону и бб.
Цитата Сообщение от IcyWind Посмотреть сообщение
2.) Где можно хранить хендл потока? Если я создам
C++
1
HANDLE potok[10]
там можно?
зачем вам 10 хэндлов? хватит одного
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 269
11.03.2012, 20:10  [ТС]     Потоки. Основа. #6
Цитата Сообщение от retmas Посмотреть сообщение
зачем вам 10 хэндлов? хватит одного
Ну я к примеру)

Печально, что приходится самому программисту заботиться о том, чтобы разделить param на то, что ему надо...

1.)
C++
1
iterator_pair p = *static_cast<iterator_pair*>(param);
тут p - это ТИП
я заменил строчку на
C++
1
iterator_pair* p = static_cast< iterator_pair * > (param);
теперь p - это указатель на ТИП. Правильно?

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "stdafx.h"
#include <Windows.h>
#include <vector>
#include <iostream>
using namespace std;
 
template <typename T>
struct para
{
    T begin,end;
    para (T b, T e)
    {
        begin = b;
        end = e;
    }
};
 
typedef para<vector<int>::iterator> iterator_pair;
 
 
 
 
DWORD WINAPI func(PVOID param)
{
    iterator_pair* p = static_cast< iterator_pair * > (param);
    while( p->begin != p->end )
    {
        cout<< *p->begin;
        ++p->begin;
    }
    return 0;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    vector<int> b;
    b.push_back(5);
    b.push_back(4);
    b.push_back(3);
    b.push_back(2);
 
    //iterator_pair p(b.begin() , b.end());
    CreateThread(NULL, 0, func, &iterator_pair(b.begin(), b.end()), 0, NULL);
    
    return 0;
}
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 20:18     Потоки. Основа. #7
Передаете временный объект и не ждете завершения потока. У вас программа сразу завершается после вызова потока.
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 269
11.03.2012, 20:20  [ТС]     Потоки. Основа. #8
А можете, пожалуйста, написать строку для ожидания завершения потока?
скажем
C++
1
2
HANDLE potok = CreateThread(NULL, 0, func, &iterator_pair(b.begin(), b.end()), 0, NULL);
While(potok.??? )
А временный объект я передаю намеренно. Разве есть ошибка?
retmas
Жарю без масла
859 / 741 / 164
Регистрация: 13.01.2012
Сообщений: 1,694
11.03.2012, 20:21     Потоки. Основа. #9
в мэйне надо дожидаться завершения потока.
и раскомментируйте свою строчку в мэйне и передавайте указатель на р, а не на временный объект
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
11.03.2012, 20:22     Потоки. Основа. #10
А почему вы пользуетесь какой-то CreateThread вместо того чтобы использовать _beginthread?
Вот вам в тему заодно пример из книги Петзолда на мультипотоковость
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
#include <windows.h>
#include <process.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
 
#define REP 1000000 // 100 000
 
#define STATUS_READY 0
#define STATUS_WORKING 1
#define STATUS_DONE 2
 
#define WM_CALC_DONE (WM_USER+0)
#define WM_CALC_ABORTED (WM_USER+1)
 
typedef struct
{
    HWND hwnd;
    BOOL bContinue;
} 
PARAMS, *PPARAMS;
 
LRESULT APIENTRY WndProc(HWND, UINT, WPARAM, LPARAM);
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, PSTR szCmdLine, int iCmdShow)
{
    static char szAppName[]="BigJob1";
    MSG msg;
    HWND hwnd;
 
    WNDCLASSEX wndclass;
 
    ZeroMemory(&wndclass, sizeof(wndclass));
 
    wndclass.cbSize=sizeof(wndclass);
    wndclass.style=CS_HREDRAW|CS_VREDRAW;
    wndclass.lpfnWndProc=WndProc;
    wndclass.hInstance=hInstance;
    wndclass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor=LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground=(HBRUSH) GetStockObject(WHITE_BRUSH);
    wndclass.lpszClassName=szAppName;
    wndclass.hIconSm=LoadIcon(NULL, IDI_APPLICATION);
    RegisterClassEx(&wndclass);
 
    hwnd=CreateWindow(szAppName, "Multithreading Demo", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL);
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);
 
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
 
void Thread(PVOID pvoid)
{
    double A=1.0;
    INT i;
    LONG lTime;
    PPARAMS pparams;
 
    pparams=(PPARAMS) pvoid;
    
    lTime=GetCurrentTime();
    for(i=0;i<REP && pparams->bContinue;i++)
        A=tan(atan(exp(log(sqrt(A*A)))))+1.0;
    if(i==REP)
    {
        lTime=GetCurrentTime()-lTime;
        SendMessage(pparams->hwnd, WM_CALC_DONE, 0, lTime);
    }
    else
        SendMessage(pparams->hwnd, WM_CALC_ABORTED, 0, lTime);
    _endthread();
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    static char *szMessage[]={"Ready (left mous button begins)",
        "Working (right mouse button aborts)",
        "%d repetitions in %ld msec"};
    static INT iStatus;
    static LONG lTime;
    static PARAMS params;
    char szBuffer[64];
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;
 
    switch(iMsg)
    {
    case WM_LBUTTONDOWN:
        if(iStatus==STATUS_WORKING)
        {
            MessageBeep(0);
            return 0;
        }
        iStatus=STATUS_WORKING;
 
        params.hwnd=hwnd;
        params.bContinue=TRUE;
 
        _beginthread(Thread, 0, &params);
        InvalidateRect(hwnd, NULL, TRUE);
        return 0;
 
    case WM_RBUTTONDOWN:
        params.bContinue=FALSE;
        return 0;
 
    case WM_CALC_DONE:
        lTime=lParam;
        iStatus=STATUS_DONE;
        InvalidateRect(hwnd, NULL, TRUE);
        return 0;
 
    case WM_CALC_ABORTED:
        iStatus=STATUS_READY;
        InvalidateRect(hwnd, NULL, TRUE);
        return 0;
 
    case WM_PAINT:
        hdc=BeginPaint(hwnd, &ps);
 
        GetClientRect(hwnd, &rect);
 
        wsprintf(szBuffer, szMessage[iStatus], REP, lTime);
 
        DrawText(hdc, szBuffer, -1, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
        EndPaint(hwnd, &ps);
        return 0;
 
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 20:26     Потоки. Основа. #11
А можете, пожалуйста, написать строку для ожидания завершения потока?
WaitForSingleObject(potok, INFINITE);

А временный объект я передаю намеренно. Разве есть ошибка?
Да, после вызова функции переданный временный объект уничтожится.
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 269
11.03.2012, 20:31  [ТС]     Потоки. Основа. #12
Хм...для лучшего понимания:
временный объект уничтожится прямо после создания потока. Поэтому в саму функцию он не попадёт.
вроде выходит так...

Добавлено через 22 секунды
Я думал, что он перестанет существовать после выхода из функции
retmas
Жарю без масла
859 / 741 / 164
Регистрация: 13.01.2012
Сообщений: 1,694
11.03.2012, 20:32     Потоки. Основа. #13
ф-я получает копию указателя. но на что он указывает? подумайте
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 20:34     Потоки. Основа. #14
IcyWind, в функцию он попадет. Но будет валиден только на первой итерации цикла поточной функции.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.03.2012, 23:22     Потоки. Основа.
Еще ссылки по теме:

Потоки в C++ - C++
Господа, можете посоветовать хорошую книгу по потокам в C++ или мануалы какие-то что ли ? Не советуйте материал найденный в поисковике,...

Потоки - C++
Как передать параметры потоку, если я его вызываю с помощью _beginthread

Потоки - C++
Доброго времени суток! Задание такое Создание списка слов отсортированных по алфавиту (выбрать алгоритм с возможностью...

VC, потоки. - C++
Вот что я написал: #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;afxwin.h&gt; UINT myproc1 (LPVOID pParam) { return 0; } ...


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

Или воспользуйтесь поиском по форуму:
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 269
11.03.2012, 23:22  [ТС]     Потоки. Основа. #15
А указывает он на только что переставший существовать объект?

Добавлено через 59 минут
Теперь вопрос в синхронизации потоков...
если на пальцах, то есть два потока.
в обоих как-то двигаюсь по итераторам (it1 и it2)
в какой-то момент времени поток останавливается и ждёт, пока остановится другой поток (собираюсь сделать это с помощью событий)
после этого нужно сделать swap(it1, it2).
Есть версия с return it1/2 из функции потока...и последующем создании новых потоков...но, мне кажется, это будет ОЧЕНЬ ресурсоёмко.
Подскажете?

Добавлено через 1 час 45 минут
ау...
Yandex
Объявления
11.03.2012, 23:22     Потоки. Основа.
Ответ Создать тему
Опции темы

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