- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 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
#ifdef WIN32
typedef DWORD (*LPTHREAD_METHOD)(LPVOID pParam);
// Структура параметров для статической функции.
typedef struct STARTUP_PARAM
{
// MSVThread* pClass;
LPTHREAD_METHOD pMethod;
LPVOID pParam;
} *LPSTARTUP_PARAM;
// Функция, которая создает новый поток.
HANDLE StartThread (LPTHREAD_METHOD pMethod, LPVOID pParam=0,
LPDWORD pdwThreadID = NULL,
LPSECURITY_ATTRIBUTES pSecurity = NULL ,
DWORD dwStackSize = 0 ,
DWORD dwFlags = 0);
// Статическая функция, которая запустит метод.
static DWORD StartFunc (LPSTARTUP_PARAM pStartup);
HANDLE StartThread(LPTHREAD_METHOD pMethod, LPVOID pParam,
LPDWORD pdwThreadID /* = NULL */,
LPSECURITY_ATTRIBUTES pSecurity /* = NULL */,
DWORD dwStackSize /* = 0 */,
DWORD dwFlags /* = 0 */)
{
// Создаем структуру и упаковываем данные для статической функции.
LPSTARTUP_PARAM pStartup = new STARTUP_PARAM;
pStartup->pMethod = pMethod;
pStartup->pParam = pParam;
// Создаем новый поток.
return CreateThread(pSecurity, dwStackSize, (LPTHREAD_START_ROUTINE)StartFunc, pStartup, dwFlags, pdwThreadID);
}
// В новом потоке вначале вызывается функция CMyClass::StartFunc(...)
// А она запускает наш метод.
DWORD StartFunc(LPSTARTUP_PARAM pStartup)
{
// Распаковываем данные в новом потоке.
// Получаем указатель на класс и на метод класса.
LPTHREAD_METHOD pMethod = pStartup->pMethod;
LPVOID pParam = pStartup->pParam;
// Запускаем метод класса в новом потоке.
DWORD dwResult = (*pMethod)(pParam);
// Удаляем временные данные и возвращаем код возврата из нового потока.
delete pStartup;
return dwResult;
}
#else
#include "pthread.h"
typedef DWORD (*LPTHREAD_METHOD)(LPVOID pParam);
// Структура параметров для статической функции.
typedef struct STARTUP_PARAM
{
LPTHREAD_METHOD pMethod;
LPVOID pParam;
} *LPSTARTUP_PARAM;
// Статическая функция, которая запустит метод.
static DWORD StartFunc (LPSTARTUP_PARAM pStartup);
// Функция, которая создает новый поток.
HANDLE StartThread(LPTHREAD_METHOD pMethod, LPVOID pParam=0,
LPDWORD pdwThreadID=0 /* = NULL */,
// LPSECURITY_ATTRIBUTES pSecurity /* = NULL */,
// DWORD dwStackSize /* = 0 */,
const pthread_attr_t* dwFlags=0 /* = 0 */)
{
// Создаем новый поток.
pthread_t restrict;
if(pthread_create(&restrict, dwFlags, (void* (*)(void*))pMethod, pParam)) return pdwThreadID;
return 0;
}
#endif
Человек пишет кросплатформенный http-сервер, а заодно свой собсвенный фреймворк. Участок кода с нитями.
guest 18.05.2009 10:31 # 0
guest 18.05.2009 14:00 # +1
boost::thread, boost::mutex, etc, м?
guest 31.05.2009 03:19 # 0
[quote=Говногость]А я говнокодер и не понял что здесь? Поясните кто-нибудь, пожалуста, а?[/quote]
А то, что человек сделал обертку над CreateThread виндовой, которая делает ровно то же самое, что и делает CreateThread.
Создает новый поток и очень изощренно вызывает каллбек.
А можно было просто
CreateThread(pSecurity, dwStackSize, pMethod, pParam, dwFlags, pdwThreadID)
like_a 08.01.2011 00:12 # 0
guest 22.06.2013 11:29 # 0
guest 31.05.2009 11:01 # 0
guest 04.06.2009 17:09 # 0
guest 14.07.2009 09:29 # 0
1. HANDLE, DWORD и прочие - специфичны для winapi, и с posix ничего общего не имеют. Пусть пишет абстрактный слой.
2. Даже если самостоятельно объявить все HANDLE, DWORD (а придётся), то в наличии большое дублирование кода - в данном случае достаточно в #ifdef засунуть несколько вызовов функций.
3. Код специфичный для разных ОС принято рассовывать по разным .c/.cpp файлам, полностью абстрагируясь от особенностей реализации и не включая в свой код уебический windows.h с его кучей макросов.