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

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

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

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

11.03.2012, 18:53. Просмотров 1611. Ответов 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.) Передача параметров. Скажем, я хочу передать в функцию два иттератора. Непонятен сам процесс передачи параметров...что мне следует делать? Загонять оба иттератора в структуру?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.03.2012, 18:53
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Потоки. Основа. (C++):

Что такое потоки ввода, потоки вывода? - C++
Здарова всем! Не так давно уже прогаю на С++ и все НИКАК не могу понять, что такое потоки ввода, потоки вывода..! вот допустим...

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

потоки.. - C++
Доброго всем времени суток. При написании программы я столкнулся с проблемой, решение которой, по словам друзей, лежит в потоках. проблема...

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

Потоки - C++
В процессе выполнения задачи возникла проблема чтения объектов из потока и сохранения их в массив: cout &lt;&lt; &quot;Rasstojanie = &quot; &lt;&lt; xx...

потоки с++ - C++
добрый вечер !нужно проверить мою программу с потоками. переделала, но что-то не так( закомменченная программа, моя на основе которой...

23
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 секунду
С итераторами вообще аккуратней. Они потокозависимы.
1
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
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]
там можно?
0
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) Хранить можно где угодно. Главное, что бы был доступ.
0
retmas
Жарю без масла
863 / 745 / 168
Регистрация: 13.01.2012
Сообщений: 1,702
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 хэндлов? хватит одного
0
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
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;
}
0
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 20:18 #7
Передаете временный объект и не ждете завершения потока. У вас программа сразу завершается после вызова потока.
0
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
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.??? )
А временный объект я передаю намеренно. Разве есть ошибка?
0
retmas
Жарю без масла
863 / 745 / 168
Регистрация: 13.01.2012
Сообщений: 1,702
11.03.2012, 20:21 #9
в мэйне надо дожидаться завершения потока.
и раскомментируйте свою строчку в мэйне и передавайте указатель на р, а не на временный объект
0
Gepar
1177 / 533 / 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);
}
0
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 20:26 #11
А можете, пожалуйста, написать строку для ожидания завершения потока?
WaitForSingleObject(potok, INFINITE);

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

Добавлено через 22 секунды
Я думал, что он перестанет существовать после выхода из функции
0
retmas
Жарю без масла
863 / 745 / 168
Регистрация: 13.01.2012
Сообщений: 1,702
11.03.2012, 20:32 #13
ф-я получает копию указателя. но на что он указывает? подумайте
0
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 20:34 #14
IcyWind, в функцию он попадет. Но будет валиден только на первой итерации цикла поточной функции.
0
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
11.03.2012, 23:22  [ТС] #15
А указывает он на только что переставший существовать объект?

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

Добавлено через 1 час 45 минут
ау...
0
11.03.2012, 23:22
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.03.2012, 23:22
Привет! Вот еще темы с ответами:

Потоки - C++
Помогите,пожалуйста!Написать программу, которая считывает текст из файла и выводит на экран только предложения, начинающиеся с тире, перед...

Потоки - C++
Задание: 1.Отображение списка запущенных потоков. 2.Создание нового потока по запросу пользователя.(это у меня сделано и работает) ...

Потоки - C++
Я нашел в интернете отличную статью про потоки и многопоточность и на её основе написал следующую программу: #include &quot;stdafx.h&quot; ...

Потоки - C++
Пару вопросов про потоки... 1. Открывается поток, в нем запускается еще один... потоки отсоединяются, как закрыть дочерний поток когда...


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

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

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