博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程学习笔记
阅读量:5090 次
发布时间:2019-06-13

本文共 8496 字,大约阅读时间需要 28 分钟。

头文件windows.h

创建线程 

HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId )

该函数在其调用进程的进程空间里创建一个新的线程,并返回已建线程的句柄。 

lpThreadAttributes:指向一个 SECURITY_ATTRIBUTES 结构的指针,该结构决定了线程的安全属性,一般置为 NULL;

dwStackSize:指定了线程的堆栈深度,一般都设置为0;
lpStartAddress:表示新线程开始执行时代码所在函数的地址,即线程的起始地址。一般情况为线程函数名;
lpParameter:指定了线程执行时传送给线程的32位参数,即线程函数的参数;
dwCreationFlags:控制线程创建的附加标志,可以取两种值。如果该参数为0,线程在被创建后就会立即开始执行;如果该参数为CREATE_SUSPENDED,则系统产生线程后,该线程处于挂起状态,并不马上执行,直至函数ResumeThread被调用;
lpThreadId:该参数返回所创建线程的ID; 如果创建成功则返回线程的句柄,否则返回NULL

 

SuspendThread(HANDLE hThread);

该函数用于挂起指定的线程,如果函数执行成功,则线程的执行被终止 .

 

DWORD ResumeThread(HANDLE hThread);

该函数用于结束线程的挂起状态,执行线程。 

 

VOID ExitThread(DWORD dwExitCode);

该函数用于线程终结自身的执行 

 

BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);

强行终止某一线程的执行

 

自己写的一个简易的线程类:

1 #include 
2 #include
3 4 class unit { 5 public: 6 void *v; //参数 7 int *ret; //返回值 8 }; 9 10 class THREAD11 {12 public:13 HANDLE hThread; //线程句柄14 DWORD ThreadID; //线程id15 LPTHREAD_START_ROUTINE IpStartAddress; //线程函数16 int ret; //返回值17 unit u; //将参数和返回值打包传入线程函数18 THREAD() { //初始化19 ret = 0;20 }21 THREAD(void *ThreadProcess) { //带参数初始化22 ret = 0;23 IpStartAddress = (LPTHREAD_START_ROUTINE)ThreadProcess;24 }25 void run() { //运行线程 26 if (IpStartAddress != NULL) {27 u = { NULL,&ret };28 hThread = CreateThread(NULL, 0, IpStartAddress, (LPVOID)&u, 0, &ThreadID);29 }30 }31 void run(void *lp) { //运行线程,并传入参数32 if (IpStartAddress != NULL) {33 u = { lp,&ret };34 hThread = CreateThread(NULL, 0, IpStartAddress, (LPVOID)&u, 0, &ThreadID);35 }36 }37 };

该类可以调用带参数的线程函数或者不带参数的线程函数,线程函数返回值类型为int,将放在ret中

使用:

1 THREAD fightthread;    //创建线程类2 fightthread.IpStartAddress = (LPTHREAD_START_ROUTINE)waitFight;//线程函数赋值3 fightthread.run();        //运行线程

线程函数定义:

void waitFight(LPVOID pM) {        unit* c=(unit*)pM;    //参数类型为上边定义的unit类,类里的参数v可以是任意类型的参数    函数体;    ......    unit->ret=0;    //线程函数返回值赋值}

 

一个线程池的实现:

1 #pragma warning(disable: 4530)  2 #pragma warning(disable: 4786)  3 #include 
4 #include
5 #include
6 #include
7 #include
8 using namespace std; 9 10 class ThreadJob //工作基类 11 { 12 public: 13 //供线程池调用的虚函数 14 virtual void DoJob(void *pPara) = 0; 15 }; 16 17 class ThreadPool 18 { 19 public: 20 //dwNum 线程池规模 21 ThreadPool(DWORD dwNum = 4) : _lThreadNum(0), _lRunningNum(0) 22 { 23 InitializeCriticalSection(&_csThreadVector); 24 InitializeCriticalSection(&_csWorkQueue); 25 _EventComplete = CreateEvent(0, false, false, NULL); 26 _EventEnd = CreateEvent(0, true, false, NULL); 27 _SemaphoreCall = CreateSemaphore(0, 0, 0x7FFFFFFF, NULL); 28 _SemaphoreDel = CreateSemaphore(0, 0, 0x7FFFFFFF, NULL); 29 assert(_SemaphoreCall != INVALID_HANDLE_VALUE); 30 assert(_EventComplete != INVALID_HANDLE_VALUE); 31 assert(_EventEnd != INVALID_HANDLE_VALUE); 32 assert(_SemaphoreDel != INVALID_HANDLE_VALUE); 33 AdjustSize(dwNum <= 0 ? 4 : dwNum); 34 } 35 ~ThreadPool() 36 { 37 DeleteCriticalSection(&_csWorkQueue); 38 CloseHandle(_EventEnd); 39 CloseHandle(_EventComplete); 40 CloseHandle(_SemaphoreCall); 41 CloseHandle(_SemaphoreDel); 42 vector
::iterator iter; 43 for (iter = _ThreadVector.begin(); iter != _ThreadVector.end(); iter++) 44 { 45 if (*iter) 46 delete *iter; 47 } 48 DeleteCriticalSection(&_csThreadVector); 49 } 50 //调整线程池规模 51 int AdjustSize(int iNum) 52 { 53 if (iNum > 0) 54 { 55 ThreadItem *pNew; 56 EnterCriticalSection(&_csThreadVector); 57 for (int _i = 0; _i
_Handle = CreateThread(NULL, 0, DefaultJobProc, pNew, 0, NULL); 62 // set priority 63 SetThreadPriority(pNew->_Handle, THREAD_PRIORITY_BELOW_NORMAL); 64 assert(pNew->_Handle); 65 } 66 LeaveCriticalSection(&_csThreadVector); 67 } 68 else 69 { 70 iNum *= -1; 71 ReleaseSemaphore(_SemaphoreDel, iNum > _lThreadNum ? _lThreadNum : iNum, NULL); 72 } 73 return (int)_lThreadNum; 74 } 75 //调用线程池 76 void Call(void(*pFunc)(void *), void *pPara = NULL) 77 { 78 assert(pFunc); 79 EnterCriticalSection(&_csWorkQueue); 80 _JobQueue.push(new JobItem(pFunc, pPara)); 81 LeaveCriticalSection(&_csWorkQueue); 82 ReleaseSemaphore(_SemaphoreCall, 1, NULL); 83 } 84 //调用线程池 85 inline void Call(ThreadJob * p, void *pPara = NULL) 86 { 87 Call(CallProc, new CallProcPara(p, pPara)); 88 } 89 //结束线程池, 并同步等待 90 bool EndAndWait(DWORD dwWaitTime = INFINITE) 91 { 92 SetEvent(_EventEnd); 93 return WaitForSingleObject(_EventComplete, dwWaitTime) == WAIT_OBJECT_0; 94 } 95 //结束线程池 96 inline void End() 97 { 98 SetEvent(_EventEnd); 99 }100 inline DWORD Size()101 {102 return (DWORD)_lThreadNum;103 }104 inline DWORD GetRunningSize()105 {106 return (DWORD)_lRunningNum;107 }108 bool IsRunning()109 {110 return _lRunningNum > 0;111 }112 protected:113 //工作线程114 static DWORD WINAPI DefaultJobProc(LPVOID lpParameter = NULL)115 {116 ThreadItem *pThread = static_cast
(lpParameter);117 assert(pThread);118 ThreadPool *pThreadPoolObj = pThread->_pThis;119 assert(pThreadPoolObj);120 InterlockedIncrement(&pThreadPoolObj->_lThreadNum);121 HANDLE hWaitHandle[3];122 hWaitHandle[0] = pThreadPoolObj->_SemaphoreCall;123 hWaitHandle[1] = pThreadPoolObj->_SemaphoreDel;124 hWaitHandle[2] = pThreadPoolObj->_EventEnd;125 JobItem *pJob;126 bool fHasJob;127 for (;;)128 {129 DWORD wr = WaitForMultipleObjects(3, hWaitHandle, false, INFINITE);130 //响应删除线程信号131 if (wr == WAIT_OBJECT_0 + 1)132 break;133 //从队列里取得用户作业134 EnterCriticalSection(&pThreadPoolObj->_csWorkQueue);135 if (fHasJob = !pThreadPoolObj->_JobQueue.empty())136 {137 pJob = pThreadPoolObj->_JobQueue.front();138 pThreadPoolObj->_JobQueue.pop();139 assert(pJob);140 }141 LeaveCriticalSection(&pThreadPoolObj->_csWorkQueue);142 //受到结束线程信号 确定是否结束线程(结束线程信号 && 是否还有工作)143 if (wr == WAIT_OBJECT_0 + 2 && !fHasJob)144 break;145 if (fHasJob && pJob)146 {147 InterlockedIncrement(&pThreadPoolObj->_lRunningNum);148 pThread->_dwLastBeginTime = GetTickCount();149 pThread->_dwCount++;150 pThread->_fIsRunning = true;151 pJob->_pFunc(pJob->_pPara); //运行用户作业152 delete pJob;153 pThread->_fIsRunning = false;154 InterlockedDecrement(&pThreadPoolObj->_lRunningNum);155 }156 }157 //删除自身结构158 EnterCriticalSection(&pThreadPoolObj->_csThreadVector);159 pThreadPoolObj->_ThreadVector.erase(find(pThreadPoolObj->_ThreadVector.begin(), pThreadPoolObj->_ThreadVector.end(), pThread));160 LeaveCriticalSection(&pThreadPoolObj->_csThreadVector);161 delete pThread;162 InterlockedDecrement(&pThreadPoolObj->_lThreadNum);163 if (!pThreadPoolObj->_lThreadNum) //所有线程结束164 SetEvent(pThreadPoolObj->_EventComplete);165 return 0;166 }167 //调用用户对象虚函数168 static void CallProc(void *pPara)169 {170 CallProcPara *cp = static_cast
(pPara);171 assert(cp);172 if (cp)173 {174 cp->_pObj->DoJob(cp->_pPara);175 delete cp;176 }177 }178 //用户对象结构179 struct CallProcPara180 {181 ThreadJob* _pObj;//用户对象 182 void *_pPara;//用户参数183 CallProcPara(ThreadJob* p, void *pPara) : _pObj(p), _pPara(pPara) { };184 };185 //用户函数结构186 struct JobItem187 {188 void(*_pFunc)(void *);//函数189 void *_pPara; //参数190 JobItem(void(*pFunc)(void *) = NULL, void *pPara = NULL) : _pFunc(pFunc), _pPara(pPara) { };191 };192 //线程池中的线程结构193 struct ThreadItem194 {195 HANDLE _Handle; //线程句柄196 ThreadPool *_pThis; //线程池的指针197 DWORD _dwLastBeginTime; //最后一次运行开始时间198 DWORD _dwCount; //运行次数199 bool _fIsRunning;200 ThreadItem(ThreadPool *pthis) : _pThis(pthis), _Handle(NULL), _dwLastBeginTime(0), _dwCount(0), _fIsRunning(false) { };201 ~ThreadItem()202 {203 if (_Handle)204 {205 CloseHandle(_Handle);206 _Handle = NULL;207 }208 }209 };210 std::queue
_JobQueue; //工作队列211 std::vector
_ThreadVector; //线程数据212 CRITICAL_SECTION _csThreadVector, _csWorkQueue; //工作队列临界, 线程数据临界213 HANDLE _EventEnd, _EventComplete, _SemaphoreCall, _SemaphoreDel;//结束通知, 完成事件, 工作信号, 删除线程信号214 long _lThreadNum, _lRunningNum; //线程数, 运行的线程数215 };
ThreadPool Code

使用:

ThreadPool tp(10);tp.Call(函数名[,函数参数]);

 

转载于:https://www.cnblogs.com/chengyu404/p/5425362.html

你可能感兴趣的文章
Java跟Javac,package与import
查看>>
day-12 python实现简单线性回归和多元线性回归算法
查看>>
Json格式的字符串转换为正常显示的日期格式
查看>>
[转]使用 Razor 进行递归操作
查看>>
[转]Android xxx is not translated in yyy, zzz 的解决方法
查看>>
docker入门
查看>>
Android系统--输入系统(十一)Reader线程_简单处理
查看>>
监督学习模型分类 生成模型vs判别模型 概率模型vs非概率模型 参数模型vs非参数模型...
查看>>
Mobiscroll脚本破解,去除Trial和注册时间限制【转】
查看>>
实验五 Java网络编程及安全
查看>>
32位与64位 兼容编程
查看>>
iframe父子页面通信
查看>>
ambari 大数据安装利器
查看>>
java 上传图片压缩图片
查看>>
magento 自定义订单前缀或订单起始编号
查看>>
ACM_拼接数字
查看>>
计算机基础作业1
查看>>
Ubuntu 深度炼丹环境配置
查看>>
C#中集合ArrayList与Hashtable的使用
查看>>
从一个标准 url 里取出文件的扩展名
查看>>