線程

-----------------------------------------------------------------------------
----------------------2016.09.22---------------------------------------------
線程是系統內核對象之一。
內核對象是系統內核分配的一個內存塊,該內存塊描述的是一個數據結構,其成員負責維護對象的各種信息。
內核對象的數據只能由系統內核來訪問。

常見的係統內核對象有:事件對象、文件對象、作業對象、互斥對象、管道對象、進程對象和線程對象。

共有屬性:
1.引用計算屬性->內核對象在進程中創建,創建時的使用計數為1,其他進程訪問該對象時,使用計數遞增1.當其使用計數為零時,系統撤銷該內核對象。
2.安全屬性->用安全描述符來表示,安全描述符描述了內核對象的創建者,有權訪問與使用的對象,能否被繼承等。

進程是一個正在運行的程序實例。
可以理解為一個容器,提供空間,執行程序的代碼由線程實現。
線程存在於進程中,負責執行進程地址空間中的代碼。
主線程:進程創建的時候,系統自動為進程創建的線程,用戶在主線程創建其他線程,主線程結束則進程結束。

線程的創建函數:Create Thread,_beginthreadex,AfxBeginThread。
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,//線程的安全屬性,可為NULL
 
SIZE_T dwStackSize,//線程棧的最大大小,可忽略
 
LPTHREAD_START_ROUTINE lpStartAddress,//線程函數,線程運行時,執行的線程入口函數--------->DWORD ThreadProd(LPVOID lpParameter);
 
LPVOID lpParameter,//向線程函數傳遞的參數
 
DWORD dwCreationFlags,//線程創建的標記
 
LPDWORD lpThreadId//整形指針,用於接收線程的ID。
)
返回值:若函數執行成功,返回線程句柄,否則返回NULL。
創建線程程序的組成:
1)包含的必要文件:要包含Windows.h文件和iostream.h文件
2)線程入口函數
3)main函數:主線程的入口函數。
-----------------------------------------------------------------------------

_beginthreadex( 
void *security,//安全
unsigned stack_size, 
unsigned ( __stdcall *start_address )( void * ),
 void *arglist, unsigned initflag,
 unsigned *thrdaddr );
 
 //第1個參數:安全?性,NULL?默認安全?性
 //第2個參數:指定線程堆棧的大小。如果為0,該線程堆棧大小和創建它的線程的大小相同。一般用0
 //第3個參數:指定線程函數的地址,也就是線程?用運行的函數地址(用函數名稱即可,函數名稱就表示地址)
 //第4個參數:指向該線程的??的指針,可以通??入?象的指?,在線程函數中再轉化為???的指針
 //第5個參數:線程初始狀態,0:立即執行;CREATE_SUSPEND:suspended(?挂)
 //第6個參數:用于??線程ID的地址

AfxBeginThread

-------------------------------------------------------------------------------------------------
創建線程的步驟:
1.創建對話框;
2.添加變量;
3.定義線程函數;
4.創建線程;
5.對話框關閉時釋放線程對象;
----------------------------------------------------------------------------------------

CWindThread類封裝了對線程的支持

該類提供了兩種類型線程,
工作者線程:線程中沒有消息循環,主要在後台進行計算或完成某些功能
用戶界面線程;具有消息循環,可處理從系統接收的消息
成員:
1.m_bAutoDelete:用於確定在線程終止時,線程對象是否自動被釋放;
2.m_hThread:表示線程對象關聯的線程句柄;
3.m_hThreadID:用於記錄線程ID;
4.m_pMainWnd用於表示應用程序的主窗口
5.m_pActiveWnd若線程是OLE服務器的一部分,該成員表示容器應用程序主窗口;
6.CreatedThread創建線程,

7.GetMainWnd獲取應用程序的窗口指針。

8.ResumeThread用於重新喚醒線程。將線程的掛起計數減1,若掛起計數為0,開始執行該線程。
若執行成功,返回線程的掛起計數,若返回為1,線程立刻執行。

9.SuspendThread用于掛起線程。
若執行成功,返回之前的掛起數。

10.ExitThread該函數用於結束當前的線程。

11.TerminateThread強制終止線程的執行。


------------------------------------------------------------------------------------
多線程應用程序中最容易出現的問題就是資源訪問衝突。
線程同步可用:事件對象、信號量對象、臨界區對象、互斥對象來實現。
------------------------------------------------------------------------------
事件對象實現線程同步:
----------------------
人工重置事件對象,自動重置事件對象。
人工重置:可以同時有多個線程等待到事件對象、成為可調度線程。
自動重置:等待該事件對象的多個線程只能有一個線程成為可調度線程。
----------------------------------------------------------------
1.CreateEvent:創建一個事件對象;

2.SetEvent:將事件設置為通知狀態;

3.ResetEvent:將事件設置為未通知狀態;

4.WaitForSingleObject:在設計線程同步時,要使用該函數來等待內核對象的狀態;
源代碼:
int number = 1;
HANDLE hEvent;//定義事件句柄
unsigned long _stdcall ThreadProc1(void* lpParameter)//線程函數
{
    long count;
    while(number<100)
    {
        WaitForSingleObject(hEvent,INFINITE);//等待事件對象為有信號狀態
        printf("Thread 1 : %d\n",number);
        number++;
        Sleep(100);
        SetEvent(hEvent);//設置事件為有信號狀態
    }
    return 0 ;
}

----------------------------------------------------------------------------
使用信號量對象實現
------------------
屬於系統內核對象之一,包含又使用計數。當使用計數為0時,信號量對象屬於無信號狀態;大於0 時,信號量對象處於有信號狀態。

1.CreateSemaphore:創建一個信號量對象;

2.ReleaseSemaphore:用於遞增信號量的使用計數;
源代碼:

int number = 1;
HANDLE hDemaphore;//信號量句柄
unsigned long _stdcall ThreadProc1(void* lpParameter)
{
    long count;
    while(number<100)
    {        
        WaitForSingleObject(hDemaphore,INFINITE);//等待信號量為有信號狀態
        printf("Thread 1 : %d\n",number);
        number++;
        Sleep(100);
        ReleaseSemaphore(hDemaphore,1,&count);//使信號量有信號&count用於返回之前信號量的使用計數
    }
    return 0 ;
}
----------------------------------------------------------------------------------------------
使用臨界區對象實現
--------------------
1.InitializeCriticalSection:用於初始化臨界區對象
在使用臨界區對象時,首先需要定義一個臨界區對象,然後進行初始化
2.EnterCriticalSection:用於等待臨界區對象的所有權;

3.LeaveCriticalSection用於釋放臨界區對象的所有權。

4.DeleteCriticalSection:用於釋放為臨界區對象分配的相關資源,是臨界區對象不再可用。

源代碼:
int number = 1;
CRITICAL_SECTION Critical;//定義臨界句柄
unsigned long _stdcall ThreadProc1(void* lpParameter)
{
    long count;
    while(number<100)
    {
        EnterCriticalSection(&Critical);//獲取臨界區對象的所有權
        printf("Thread 1 : %d\n",number);
        number++;
        Sleep(100);
        LeaveCriticalSection(&Critical);//釋放臨界區對象的所有權
    }
    return 0 ;
}

-----------------------------------------------------------------------------------------------
使用互斥對象實現
-----------------
互斥對象使線程擁有對某個資源的絕對訪問權。
互斥對象主要包含:使用數量、線程ID(當前擁有互斥對象的線程)和遞歸計數器(線程擁有互斥對象的次數)等信息。

使用方式:當互斥對象為零時:表示互斥對象不被任何線程所擁有,此時系統會發出該互斥對象的通知信號,
                等待互斥對象的某個線程將會擁有蓋互斥對象,同時互斥對象的線程ID為擁有該互斥對象的線程ID。
      當互斥對象不為零時:表示當前線程擁有該互斥對象,系統不會發出該互斥對象的通知信號,
                其他等待互斥對象的線程將繼續等待,知道擁有互斥對象的線程釋放互斥對象的所有權。

1.CreateMutex:創建一個互斥對象,返回所創建的互斥對象的句柄;
參數一:指向結構體SECURITY_ATTRIBUTES的指針;
參數二:BOOL 指定互斥對象初始的擁有者;
參數三:指定互斥對象的名稱,若為NULL,則創建一個匿名的互斥對象。
2.ReleaseMutex:釋放互斥對象的所有權;
參數:HANDLE型,需要釋放的互斥對象的句柄。
源代碼:
int number = 1;
HANDLE hMutex;//互斥對象句柄
unsigned long _stdcall ThreadProc1(void* lpParameter)
{
    long count;
    while(number<100)
    {
        WaitForSingleObject(hMutex,INFINITE);//等待互斥對象的所有權
        printf("Thread 1 : %d\n",number);
        number++;
        Sleep(100);
        ReleaseMutex(hMutex);//釋放互斥對象的所有權
    }
    return 0 ;
}
------------------------------------------------------------------------------------------------------------------

WaitForSingleObject函數

等待直到指定的對象處於有信號狀態或超時返回。
原型: 
 
DWORD WINAPI WaitForSingleObject(
    __in  HANDLE hHandle,        //被等待的對象句柄;
    __in  DWORD dwMilliseconds    //超時時間
    );

-------------------------------------------------------------------------------------------
WaitForMultipleObjects函數
等待直到一個或所有指定的對象處於有信號狀態或超時。
原型: 
DWORD WINAPI WaitForMultipleObjects(
    __in  DWORD nCount,                //表示lpHandles指向的數組中對象句柄的數量,最大值為 MAXIMUM_WAIT_OBJECTS;
    __in  const HANDLE *lpHandles,    //指向包含一組句柄對象的數組;                            
    __in  BOOL bWaitAll,            //為TRUE,表示數組lpHandles中所有對象變為有信號狀態才返回;為FALSE,表示任一對象變為有信號狀態即返回;
    __in  DWORD dwMilliseconds        //意義同WaitForSingleObject;

--------------------------------------------------------------------------------------------------


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值