
Эксперт
   
Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004
Репутация: 1 Всего: 20
|
Цитата(bsa @ 21.10.2006, 15:34 ) | | А вот с потоками придется сложнее, |
Самое простое: | Код | /***************************************************************************** * usync.h * ******************************************************************************* * Wrapper under mutex,threads create-destroy system calls * * Cross-platform!(Linux-Windows) * * Author: Paul Nujdin aka En_t_end. Barnaul 2006(Russia) * * e-mail: [email protected] * * USE THIS SOURCE OR PART OF THIS ONLY IN FREE PROJECT OR IN OPENSOURCE * * OR WITH SPECIAL ALLOWING BY PAUL NUJDIN. * ******************************************************************************/
#ifndef __USYNC_H__ #define __USYNC_H__
//Special defined options for other platform and compiler. #define PLFRM_CMPL_NIX_G//*nix-system with g++ compiler. #define PLFRM_CMPL_WINNT_VS6_7//windows nt-system with IDE VISUAL STUDIO 6-7. //*****************************************************************************
#undef PLFRM_CMPL_NIX_G //#undef PLFRM_CMPL_WINNT_VS6_7
#ifdef PLFRM_CMPL_NIX_G #include <unistd.h> #include <sys/types.h> #include <errno.h> #include <pthread.h> /* For information: For unix-base system you must linked APP with -lpthread directive, for example: g++ file.cpp -lpthread -o */ #endif //PLFRM_CMPL_NIX_G
#ifdef PLFRM_CMPL_WINNT_VS6_7 #include <windows.h> #endif //PLFRM_CMPL_WINNT_VS6_7
#ifdef PLFRM_CMPL_WINNT_VS6_7 #define USLEEP(milsec) Sleep(milsec) #define SLEEP(sec) Sleep(sec*1000) #endif //PLFRM_CMPL_WINNT_VS6_7 #ifdef PLFRM_CMPL_NIX_G #define USLEEP(milsec) usleep(milsec*1000)//milsec to micsec(10^-6 to 10^-3) #define SLEEP(sec) sleep(sec) #endif //PLFRM_CMPL_NIX_G
#define TIME_SYNC 50 //[milsec]. Time for switch other threads
namespace usync { namespace threads { #ifdef PLFRM_CMPL_WINNT_VS6_7 typedef HANDLE _hndle_; #endif //PLFRM_CMPL_WINNT_VS6_7 #ifdef PLFRM_CMPL_NIX_G typedef pthread_t* _hndle_; #endif //PLFRM_CMPL_NIX_G
typedef void* (*LPTHRD_PROC_ADDR)(void*); bool CreateThrd(_hndle_&,LPTHRD_PROC_ADDR,void*); bool CloseHndle(_hndle_);//free mem,don't close thread proc // void SuspendThrd(_hndle_); // void TerminateThrd(_hndle_); } namespace mutex { #ifdef PLFRM_CMPL_NIX_G typedef pthread_mutex_t _mutex_; #endif //PLFRM_CMPL_NIX_G #ifdef PLFRM_CMPL_WINNT_VS6_7 typedef CRITICAL_SECTION _mutex_; #endif //PLFRM_CMPL_WINNT_VS6_7
bool InitializeMutex(_mutex_*); void DestroyMutex(_mutex_*); void LockMutex(_mutex_*); void UnLockMutex(_mutex_*);
//TryLockMutex: #ifdef PLFRM_CMPL_NIX_G bool TryLockMutex(_mutex_*); #endif //PLFRM_CMPL_NIX_G #ifdef PLFRM_CMPL_WINNT_VS6_7 #ifdef _WIN32_WINNT //Windows version will work only, if windows libs compiled with _WIN32_WINNT 0x0400 constant bool TryLockMutex(_mutex_*); #endif //_WIN32_WINNT 0x0400 #endif //PLFRM_CMPL_WINNT_VS6_7 } }
#endif //__USYNC_H__
|
| Код | /****************************************************************************** * usync.cpp * ******************************************************************************* * Wrapper under mutex,threads create-destroy system calls * * Cross-platform!(Linux-Windows) * * Author: Paul Nujdin aka En_t_end. Barnaul 2006(Russia) * * e-mail: [email protected] * * USE THIS SOURCE OR PART OF THIS ONLY IN FREE PROJECT OR IN OPENSOURCE * * OR WITH SPECIAL ALLOWING BY PAUL NUJDIN. * ******************************************************************************/
#include "usync.h"
bool usync::threads::CreateThrd( usync::threads::_hndle_ &hndle, usync::threads::LPTHRD_PROC_ADDR proc, void* param) { #ifdef PLFRM_CMPL_NIX_G return (pthread_create(hndle,NULL,proc,param)==0); #endif //PLFRM_CMPL_NIX_G #ifdef PLFRM_CMPL_WINNT_VS6_7 hndle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)proc,param,0,NULL); return(hndle!=NULL); #endif //PLFRM_CMPL_WINNT_VS6_7 }
bool usync::threads::CloseHndle( usync::threads::_hndle_ hndle) { #ifdef PLFRM_CMPL_NIX_G pthread_detach(*hndle); return true; #endif //PLFRM_CMPL_NIX_G #ifdef PLFRM_CMPL_WINNT_VS6_7 return (CloseHandle(hndle)!=0); #endif //PLFRM_CMPL_WINNT_VS6_7 }
bool usync::mutex::InitializeMutex( usync::mutex::_mutex_* mutex) { #ifdef PLFRM_CMPL_NIX_G return pthread_mutex_init(mutex,NULL)==0?true:false; #endif //PLFRM_CMPL_NIX_G #ifdef PLFRM_CMPL_WINNT_VS6_7 try{InitializeCriticalSection(mutex);} catch(...){return false;} return true; #endif //PLFRM_CMPL_WINNT_VS6_7 }
void usync::mutex::DestroyMutex( usync::mutex::_mutex_* mutex) { #ifdef PLFRM_CMPL_NIX_G //multithread::multithread_mutex::UnLockMutex(mutex); //caution!!!in LinuxThread mutex must be unlocked before destroy pthread_mutex_destroy(mutex); #endif //PLFRM_CMPL_NIX_G #ifdef PLFRM_CMPL_WINNT_VS6_7 DeleteCriticalSection(mutex); #endif //PLFRM_CMPL_WINNT_VS6_7 }
void usync::mutex::LockMutex( usync::mutex::_mutex_* mutex) { #ifdef PLFRM_CMPL_NIX_G pthread_mutex_lock(mutex); #endif //PLFRM_CMPL_NIX_G #ifdef PLFRM_CMPL_WINNT_VS6_7 EnterCriticalSection(mutex); #endif //PLFRM_CMPL_WINNT_VS6_7 }
void usync::mutex::UnLockMutex( usync::mutex::_mutex_* mutex) { #ifdef PLFRM_CMPL_NIX_G pthread_mutex_unlock(mutex); #endif //PLFRM_CMPL_NIX_G #ifdef PLFRM_CMPL_WINNT_VS6_7 LeaveCriticalSection(mutex); #endif //PLFRM_CMPL_WINNT_VS6_7 }
#ifdef PLFRM_CMPL_NIX_G bool usync::mutex::TryLockMutex( usync::mutex::_mutex_* mutex) {return (pthread_mutex_trylock(mutex)!=EBUSY);} #endif //PLFRM_CMPL_NIX_G #ifdef PLFRM_CMPL_WINNT_VS6_7 #ifdef _WIN32_WINNT //Windows version will work only, if windows lib's compiled with _WIN32_WINNT 0x0400 constant bool usync::mutex::TryLockMutex( usync::mutex::_mutex_* mutex) {return (TryEnterCriticalSection(mutex)!=0);} #endif //_WIN32_WINNT 0x0400 #endif //PLFRM_CMPL_WINNT_VS6_7
|
Приминение: | Код | #include "usync.h" #include <iostream>
using std::cout; using std::endl;
using namespace usync::threads; using namespace usync::mutex;
_mutex_ MutexFor_M;// //_mutex_ MutexFor_M = PTHREAD_MUTEX_INITIALIZER; //for LinuxThread(only statically). int g_M;
void *Thread1(void* pParam) // { /* while(true) {*/ // USLEEP(20); // LockMutex(&MutexFor_M);//Ждём освобождения мутекса, занимаем мутекс... g_M = 0xDEAD;//:----) cout << "Thread1 is locked mutex, g_M = " << g_M << endl; // UnLockMutex(&MutexFor_M);//Освобождаем мутекс... // } return NULL; }
void *Thread2(void* pParam) { /* while(true) {*/ // USLEEP(30); // LockMutex(&MutexFor_M); g_M = 0xBEEF;//:----) cout << "Thread2 is locked mutex, g_M = " << g_M << endl; // UnLockMutex(&MutexFor_M); // } return NULL; }
void main() { g_M = 0; // cout << std::boolalpha; cout << "InitializeMutex -" << InitializeMutex(&MutexFor_M) << endl; // _hndle_ Hndl1,Hndl2; //Test Start-Close: cout << "Start Thread1 -" << CreateThrd(Hndl1,Thread1,NULL) << ". Close handle -" << CloseHndle(Hndl1) << endl; // cout << "Start Thread2 -" << CreateThrd(Hndl2,Thread2,NULL) << ". Close handle -" << CloseHndle(Hndl2) << endl; cout << std::hex;//for dead-beef output... //Agressive test: while(true)// ;-) { CreateThrd(Hndl1,Thread1,NULL);CloseHndle(Hndl1); CreateThrd(Hndl2,Thread2,NULL);CloseHndle(Hndl2); USLEEP(17);// } }
|
| Код | кроссплатформенный враппер над системными вызовами mutex,thread -create-destroy
Может кому пригодиться... Чтобы включить опции для нужной платформы комментим следующее в usync.h:(хотя наверное лучше, наоборот,включать это при компиляции) #undef PLFRM_CMPL_NIX_G //для никсов с g++'ом #undef PLFRM_CMPL_WINNT_VS6_7 //для windows 9x-NT VS6-7, но скорее всего и для более старых версий Под mac я не программировал, но скорее всего при минимальных усилиях можно добавить в оболочку и его системные вызовы.
Сам враппер sync.h и sync.cpp Состоит из одного namespace, в который вложенно ещё два. Один для потоков, другой для мутексов. В каждом namespac'е включены нужные функции и процедуры. Также, есть два типа процедуры усыпления текущего потока: USLEEP - послать поток в анабиоз на milsec миллисекунд;SLEEP - на sec секунд.
В примере, как пользоваться оболочкой(пример для VISUAL STUDIO 7 2003 NET). Поясню, в примере крутятся два типа потоков, каждый, получив доступ к области(global integer variable), защищенной мутексом, пишет туда либо 0xDEAD, либо 0xBEEF. Там ясно видно, как инициализировать мутекс, как его запустить, как запустить поток и освободить ресурсы. В примере, также, показан стресс-тест оболочки(super long loop). Есть также TryLockMutex - но она доступна(для win-base system) лишь при включении _WIN32_WINNT 0x0400(и выше) перед включением windows.h, то есть для старых "окон" заюзать её не получиться.
|
PS лень комменты в примере убирать... не помню уже и зачем коментил, но логика должна быть понятна... извините за мусор в коде Добавлено @ 18:47 Цитата(bsa @ 21.10.2006, 15:34 ) | | Если я не ошибаюсь, работа с сокетами в Windows и *nix очень похожа. |
Схожа да не очень, насколько я могу судить(у меня есть, хоть и скудный, опыт работы и в *nix и в windows) чтобы голова постоянна не болела придется писать универсальную библиотеку над сокетами(я поступил именно так).
|