執行緒
執行緒是進程中的一個實體,是被系統獨立調度和分配的基本單位。一個進程可以有多個執行緒,一個執行緒必須有一個父進程,執行緒自己不擁有系統資源,只有運行必須的一些數據結構,但它可以與同屬一個進程的其他執行緒共享進程所擁有的全部資源,一個執行緒可以創建和撤銷另一個執行緒,同一個進程中的多個執行緒之間可以並發執行。
多執行緒
由於執行緒之間的相互制約,致使執行緒在運行中呈現出間斷性,執行緒也有就緒、阻塞、和運行3種基本狀態,所以,在一個進程中可以創建幾個執行緒來提高程式的執行效率,並且有些程式還通過採用多執行緒技術來同事執行多個不同的代碼模組。
在一般情況下,創建一個執行緒是不能提高程式的執行效率的,所以要創建多個執行緒。但是多個線程同時運行的時候可能調用執行緒函式,在多個執行緒同時對同一個記憶體地址進行寫入,由於CPU時間調度上的問題,寫入數據會被多次的覆蓋,所以就要使執行緒同步。
即當有一個執行緒在對記憶體進行操作時,其他執行緒都不可以對這個記憶體地址進行操作,直到該執行緒完成操作,
其他執行緒才能對該記憶體地址進行操作,而其他執行緒又處於等待狀態,目前實現執行緒同步的方法有很多,臨界區對
象就是其中一種。
定義在數據段中的一個CURITY_ATTRIBUTES結構,Windows內部使用這個結構記錄一些信息,確保在同一時間只有一個執行緒訪問該數據段中的數據。
臨界區的使用步驟:1.初始化一個CURITY_ATTRIBUTES結構,在臨界區對象之前,需要定於全局CURITY_ATTRIBUTES結構變數,在調用CreateThread函式前調用InitializeCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函式初始化臨界區對象。
2.申請進入一個臨界區。線上程函式中要對保護的數據進行操作前,可以通過調用 EnterCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函式申請進入臨界區,由於在同一時間內,只允許一個執行緒進入臨界區,所以在申請的時候如果有一個執行緒進入到臨界區,則該函式就會一直等到那個執行緒執行完臨界區代碼。
3.離開臨界區。當執行完臨界區代碼後,需要調用LeaveCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函式吧臨界區交還給系統。
4.刪除臨界區,當不需要臨界區是可以調用DeleteCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函式將臨界區對象刪除
CreateThread函式說明
編程時,如果調用CreateThread函式,系統將創建一個進程和一個主執行緒。CreateThread將在主執行緒的基礎上創建一個新執行緒,如果調用成功返回新執行緒的句柄,函式調用格式:
HANDLE CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);
指向CURITY_ATTRIBUTES的指針,用於定義新縣城的安全屬性,一般設定為NULL。
dwStackSize:分配一直結束表示的執行緒堆疊的大小,其默認值為NULL。
lpStartAddress:指向一個執行緒函式地址,每個執行緒都有自己的執行緒函式,而執行緒函式式執行緒具體執行的代碼。
lpParameter:傳遞給執行緒函式的參數。
dwCreationFlags:表示創建執行緒的運行狀態,其中CREAT_SUSPEND表示掛起當前創建的執行緒,而0表示立即執行當前創建的執行緒。
lpThreadId:返回心創建執行緒對應的的ID編號。
多執行緒與執行緒同步的C++具體實現代碼:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
HANDLE hFile;
CRITICAL_SECTION cs; //定義臨界區對象
DWORD WINAPI Thread(LPVOID lpParam) //寫檔案執行緒函式
{
int n=(int)lpParam; //得到的執行緒
DWORD dwWrite;
for (int i=0;i<10000;i++)
{ //進入臨界區
EnterCriticalSection(&cs);
char Data[512]="---------by啊啊啊阿修羅--------- \r\n---------http://314755337.qzone.qq,com---------";
WriteFile(hFile,&Data,strlen(Data),&dwWrite,NULL); //寫入檔案
LeaveCriticalSection(&cs); //出臨界區
}
printf("第%d 號執行緒結束運行\n",n); // 輸出執行緒運行結束
return(0);
}
int _tmain (int argc, char* argv[ ])
{
int aaa;
hFile=CreateFile(L"C://a.text",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); //創建檔案
if(hFile==INVALID_HANDLE_VALUE)
{
printf("CreateFile Error\n");
return(0);
}
DWORD ThreadId;
HANDLE hThread[5];
InitializeCriticalSection(&cs);// 初始化臨界區對象
for(int i=0;i<5;i++) //創建5個執行緒
{
hThread[i]=CreateThread(NULL,NULL,Thread,LPVOID(i+1),0,&ThreadId);
printf("第%d 號執行緒創建成功\n",i);
}
WaitForMultipleObjects(5,hThread,true,INFINITE);//等待5個執行緒運行結束
DeleteCriticalSection(&cs);//刪除臨界區對象
CloseHandle(hFile);//關閉檔案句柄
scanf("%d",&aaa);
return(0);
}