Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/12: Рейтинг темы: голосов - 12, средняя оценка - 5.00
146 / 146 / 32
Регистрация: 26.10.2008
Сообщений: 782

Многопоточность

15.03.2010, 01:22. Показов 2660. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Мне нужно сделать класс, от которого можно наследовать ещё какой-нибудь класс с какой-то определённой функцией и определенными параметрами для создания потока.
Создал класс AbstractThread с виртуальной функцией.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class AbstractThread
{
public:
    AbstractThread()
    {
        hThread = CreateThread(
            NULL,               // Защита по умолчанию
            0,                  // Размер стека по умолчанию
            ThreadFunction,     // Имя функции
            void *,             // Входные параметры
            CREATE_SUSPENDED,   // Создать приостановленным
            &result);           // Возвращаемое значение
    }
    
    virtual DWORD WINAPI ThreadFunction(LPVOID lpParam) = 0;
private:
    HANDLE hThread;
    DWORD result;
};
Появляются ошибки:
Code
1
 error C3867: 'AbstractThread::ThreadFunction': function call missing argument list; use '&AbstractThread::ThreadFunction' to create a pointer to member
Code
1
error C2062: type 'void' unexpected
Что это за ошибки и сделать так, чтобы можно было использовать любые входные параметры?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.03.2010, 01:22
Ответы с готовыми решениями:

Многопоточность
Имеется приложение на Си в VS 2008. Приложение может создать большое количество экземпляров клиента для разных серверов (named pipes)...

Многопоточность
Здрасьте! Люди, на этом форуме нашел ценный ответ по реализации мультипотоковых программах. #include <windows.h> #include...

Многопоточность в MFC
Доброе время суток. Возник ряд вопросов, касающихся реализации многопточности на MFC. Поток создаю с помощью функции: ...

13
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
15.03.2010, 07:06
а что ты хотел?
посмотри внимательно на свой вызов:
C++
1
2
3
4
5
6
7
                hThread = CreateThread(
                        NULL,                           // Защита по умолчанию
                        0,                                      // Размер стека по умолчанию
                        ThreadFunction,         // Имя функции
                        void *,                         // Входные параметры
                        CREATE_SUSPENDED,       // Создать приостановленным
                        &result);                       // Возвращаемое значение
void *, // Входные параметры
ты вызываешь функцию с указателем в никуда. сама переменная lpParam - то где?
1
146 / 146 / 32
Регистрация: 26.10.2008
Сообщений: 782
15.03.2010, 07:52  [ТС]
Спасибо! Это я исправил:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class AbstractThread
{
public:
    AbstractThread(LPVOID inP)
    {
        in = inP;
 
        hThread = CreateThread(
            ...
            in,             // Входные параметры
                                 ...);          
    }
    
    virtual DWORD WINAPI ThreadFunction(LPVOID lpParam) = 0;
private:
           ...
    LPVOID in;
};
Но первая ошибка осталась. Не хочет с абстактной функцией работать.
Как это исправить?
0
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
15.03.2010, 08:04
Цитата Сообщение от qwert Посмотреть сообщение
Как это исправить?
написано-же английским языком:
use '&AbstractThread::ThreadFunction' to create a pointer to member

C++
1
2
3
4
5
             hThread = CreateThread(
...
&ThreadFunction,
...
);
0
146 / 146 / 32
Регистрация: 26.10.2008
Сообщений: 782
15.03.2010, 15:40  [ТС]
Да вот в том-то и дело, что вариант &ThreadFunction не проходит.
Выходит ошибка:
Code
1
error C2276: '&' : illegal operation on bound member function expression
Как можно по другому задать в параметры имя функции?
0
 Аватар для oxotnik
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
15.03.2010, 16:17
ф-я потока должна быть статической
0
146 / 146 / 32
Регистрация: 26.10.2008
Сообщений: 782
15.03.2010, 16:24  [ТС]
Можно сделать её статической, но тогда пропадает весь смысл от создания этого класса.
Смысл в том, чтобы сделать один абстрактный класс, который имеет все функции необходимые для работы с потоком, и потом наследоваться от него, чтобы переопределить функцию, которая должна выполняться в потоке.
0
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
15.03.2010, 16:37
Цитата Сообщение от qwert Посмотреть сообщение
Да вот в том-то и дело, что вариант &ThreadFunction не проходит.
само собой.
для вызова CreateThread нужна статическая функция.
нестатическая функция класса НЕ МОЖЕТ быть функцией потока: у них разные сигнатуры, и что хуже - соглашения по вызову.
надо либо делать функцию статической(но тогда она не будет иметь доступ к нестатическим членам класса), либо вообще выносить ее в глобальное пространство имен.
еще как вариант - сделать функцию статическим членом класса, но передать ей в качестве параметра this.
и уже через него получать доступ к объекту.
1
 Аватар для oxotnik
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
15.03.2010, 16:46
жаль что ссылки не разрешены, вот объяснение и как это решается:
Господа,
извиняюсь за тупость, но почему в отдельный поток можно кидать только статическую функцию-член класса. До конца не понимаю (может из-за недосыпания).
Потому, что статическая функция-член имеет такой же тип, как и обычная ф-ция (в отличее от нестатической фун-ции-члена). В win32 и POSIX ф-ция создания потока принимает указатель именно на обычную ф-цию. Но это вовсе не значит, что ты не можешь направить поток в ф-цию-член, просто для этого тебе придется использовать переходник, который будет перенаправлять поток в функцию-член:


Code
1
2
3
4
5
6
template<class T, DWORD(T::*mem_fun)()>
inline
DWORD WINAPI thread_to_member_thunk(void* p)
{
     return (static_cast<T*>(p)->*mem_fun)();
}

Используем:

Code
1
2
3
4
5
6
7
8
9
10
11
struct some
{
     DWORD f() { return 0; }
};
 
int main()
{
     some s;
     // в качестве параметра (lpParam) передаем указатель на объект, чтобы переходник направил поток именно в этот объект
     CreateThread(0, 0, thread_to_member_thunk<some, &some::f>, &s, 0, 0);
}
1
146 / 146 / 32
Регистрация: 26.10.2008
Сообщений: 782
15.03.2010, 17:07  [ТС]
oxotnik, пример хороший, попытаюсь применить.

Цитата Сообщение от Patch Посмотреть сообщение
сделать функцию статическим членом класса, но передать ей в качестве параметра this
А как такой подход выглядит на практике?
0
 Аватар для oxotnik
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
15.03.2010, 17:11
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
DWORD WINAPI ThreadFunction(LPVOID lpParam);
class AbstractThread
{
public:
        AbstractThread()
        {
                hThread = CreateThread(NULL, 0, ThreadFunction, (void*) this, CREATE_SUSPENDED, &result);
        }
private:
        HANDLE hThread;
        DWORD result;
};
 
DWORD WINAPI ThreadFunction(LPVOID lpParam)
{
   AbstractThread *params = (AbstractThread *)lpParam;
..........
   return 0;
}
1
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
15.03.2010, 17:43
лучше в статик - и внутрь класса.
0
DmiTrue
20.03.2010, 00:42
oxotnik, извините, конечно ,но я не могу понять, как к вам в голову приходят такие витееватые решения
Насколько мне извесно,LPVOID lpParameter используется примерно для следующих целей:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
DWORD WINAPI MyThread(LPVOID lpParameter)
{
    BOOL *Active;
    Active = (BOOL*)lpParameter;
    *Active = TRUE;    // флаг активности потока
 
    // Код
 
    *Active = FALSE;  // Сбрасываем флаг активности
}
 
void InitThread()
{
hThread = CreateThread(NULL, 0,
                           (LPTHREAD_START_ROUTINE)MyThread,
                           (void*)&Active, 0, &ThreadId);
 
    // Ждем завершения выполнения потока,
    // проверяя состояние флага
    while(Active == TRUE);
}
Но для чего нужно делать преобразование
C++
1
2
LPVOID lpParam;
AbstractThread *params = (AbstractThread *)lpParam;
для меня остается загадкой
Обьясните,с какой целью вы это сделали?
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
20.03.2010, 01:01
Цитата Сообщение от DmiTrue Посмотреть сообщение
для меня остается загадкой
Обьясните,с какой целью вы это сделали?
очевидно же, чтобы получить доступ к членам объекта
надо либо функцию объявлять френдовой, либо в статическую функцию передать указатель this, так как статическая функция имеет доступ ко всем закрытым членам, но физически не связана с экземпляром класса
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.03.2010, 01:01
Помогаю со студенческими работами здесь

Простое приложение для MFC, использующее многопоточность
Прошу помочь написатьпростое использование многопоточности в mfc visual c++, все перечитал,написать рабочий код каждый раз не могу

Многопоточность в Windows.Forms: вопрос реализации в общем
Всем добрый день. Только начинаю изучать с++, пользуюсь microsoft visual c++ 2010. возникла такая задача, необходимо написать многопоточное...

[Многопоточность] Как в функцию, которая будет выполняться в отдельном потоке, передать нужные аргументы?
Есть функция: UINT control1(LPVOID Param) { char msg;char pr=&quot;w&quot;; while(true){ for(i=1;i&lt;=16;i++) ...

C++ Многопоточность
Как сделать так, чтобы эта программа заработала? А то она мне вот что пишет: g++ test.cpp -o test -lpthread ./test ...

Многопоточность [Теория]
Всем привет. Что создается конструктивно в памяти при многопоточности(конкретно при инициализации потока)?


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! в-строка - входное арифметическое выражение в инфиксной(обычной). . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru