1、問題描述
如圖:

(1)服務端負責下發任務;且每次下發一個任務,下發任務個數不固定(通過下發界面勾選下發),但總個數<=4個。
(2)用戶端負責接收任務,接收任務後要循環執行,除非接收到停止指令後停止執行。
指令類型分為:
1)心跳指令——用于保活連接配接;
2)任務開始指令——用于開始執行任務;
3)任務中止指令——用于結束任務;
2、設計詳解
(1)用戶端要并發運作,且會調用相同接口傳遞不同參數實作,是以必須進行多線程同步。
線程數目由用戶端Socket接收資訊解析後而定,但總數目會<=4,未來可能會拓展。
是以,此處使用Semaphore信号量進行同步。
(2)相同代碼段,為避免通路沖突,導緻異常。需要使用“關鍵代碼段”Critical Section進行互斥通路。
3、模拟代碼
#include <stdio.h>
#include <process.h>
#include <windows.h>
long g_nNum = 0;
unsigned int __stdcall Fun(void *pPM);
const int g_iMaxThreadCnt = 4; //用戶端線程個數
//信号量與關鍵段
HANDLE g_hThreadParam;
CRITICAL_SECTION g_csThreadCode;
unsigned int __stdcall Fun(void *pPM)
{
int nThreadNum = *(int *)pPM;
EnterCriticalSection(&g_csThreadCode);
while(1)
{
++g_nNum;
printf("線程No為%d 全局資源值為%d\n", nThreadNum, g_nNum);
ReleaseSemaphore(g_hThreadParam, 1, NULL);//信号量++
LeaveCriticalSection(&g_csThreadCode);
Sleep(1000);//模拟執行
}
return 0;
}
int TestMyThread()
{
//初始化信号量和關鍵段
//目前0個資源,最大允許1個同時通路
g_hThreadParam = CreateSemaphore(NULL, 0, 1, NULL);
InitializeCriticalSection(&g_csThreadCode);
HANDLE hThread[g_iMaxThreadCnt] = {NULL};
g_nNum = 0;
int i = 0;
while (i < g_iMaxThreadCnt)
{
hThread[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);
WaitForSingleObject(g_hThreadParam, INFINITE);//等待信号量>0
++i;
}
//等待所有線程結束
WaitForMultipleObjects(g_iMaxThreadCnt, hThread, TRUE, INFINITE);
//銷毀信号量和關鍵段
DeleteCriticalSection(&g_csThreadCode);
CloseHandle(g_hThreadParam);
for (i = 0; i < g_iMaxThreadCnt; i++)
{
CloseHandle(hThread[i]);
}
return 0;
}
4、小結
1)實際項目中要比這複雜很多,涉及socket資料接收與解析、循環執行等。
循環執行線上程内部實作比較好,這樣不必循環調用線程,産生不必要的開銷。
2)心中要先有框圖内容,并思考如何執行,多測試以驗證執行結果和預期、編碼是否完全一緻。
3)API經常不用會不熟悉,一定要MSDN清楚每個字段的切實含義,避免“自以為是”,影響大局。
2015-8-30 am11:58 整理于家中床前
作者:銘毅天下
轉載請标明出處,原文位址:
http://blog.csdn.net/laoyang360/article/details/48103473如果感覺本文對您有幫助,請點選‘頂’支援一下,您的支援是我堅持寫作最大的動力,謝謝!
來源:CSDN
原文:
https://blog.csdn.net/laoyang360/article/details/48103473版權聲明:本文為部落客原創文章,轉載請附上博文連結!