日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用CreateThread函数创建线程

發(fā)布時間:2023/11/30 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用CreateThread函数创建线程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

線程是進程中的一個實體,是被系統(tǒng)獨立調(diào)度和分派的基本單位。一個進程可以擁有多個線程,但是一個線程必須有一個進程。線程自己不擁有系統(tǒng)資源,只有運行所必須的一些數(shù)據(jù)結(jié)構(gòu),但它可以與同屬于一個進程的其它線程共享進程所擁有的全部資源,同一個進程中的多個線程可以并發(fā)執(zhí)行。

在C/C++中可以通過CreateThread函數(shù)在進程中創(chuàng)建線程,函數(shù)的具體格式如下:

HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadID);參數(shù)的含義如下:

lpThreadAttrivutes:指向SECURITY_ATTRIBUTES的指針,用于定義新線程的安全屬性,一般設(shè)置成NULL;

dwStackSize:分配以字節(jié)數(shù)表示的線程堆棧的大小,默認值是0;

lpStartAddress:指向一個線程函數(shù)地址。每個線程都有自己的線程函數(shù),線程函數(shù)是線程具體的執(zhí)行代碼;

lpParameter:傳遞給線程函數(shù)的參數(shù);

dwCreationFlags:表示創(chuàng)建線程的運行狀態(tài),其中CREATE_SUSPEND表示掛起當前創(chuàng)建的線程,而0表示立即執(zhí)行當前創(chuàng)建的進程;

lpThreadID:返回新創(chuàng)建的線程的ID編號;

如果函數(shù)調(diào)用成功,則返回新線程的句柄,調(diào)用WaitForSingleObject函數(shù)等待所創(chuàng)建線程的運行結(jié)束。函數(shù)的格式如下:

DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);參數(shù)的含義如下:

hHandle:指定對象或時間的句柄;

dwMilliseconds:等待時間,以毫秒為單位,當超過等待時間時,此函數(shù)返回。如果參數(shù)設(shè)置為0,則該函數(shù)立即返回;如果設(shè)置成INFINITE,則該函數(shù)直到有信號才返回。

一般情況下需要創(chuàng)建多個線程來提高程序的執(zhí)行效率,但是多個線程同時運行的時候可能調(diào)用線程函數(shù),在多個線程同時對一個內(nèi)存地址進行寫入操作,由于CPU時間調(diào)度的問題,寫入的數(shù)據(jù)會被多次覆蓋,所以要使線程同步。

就是說,當有一個線程對文件進行操作時,其它線程只能等待。可以通過臨界區(qū)對象實現(xiàn)線程同步。臨界區(qū)對象是定義在數(shù)據(jù)段中的一個CRITICAL_SECTION結(jié)構(gòu),Windows內(nèi)部使用這個結(jié)構(gòu)記錄一些信息,確保同一時間只有一個線程訪問改數(shù)據(jù)段中的數(shù)據(jù)。

使用臨界區(qū)的步驟如下:

(1)初始化一個CRITICAL_SECTION結(jié)構(gòu);在使用臨界區(qū)對象之前,需要定義全局CRITICAL_SECTION變量,在調(diào)用CreateThread函數(shù)前調(diào)用InitializeCriticalSection函數(shù)初始化臨界區(qū)對象;

(2)申請進入一個臨界區(qū);在線程函數(shù)中要對保護的數(shù)據(jù)進行操作前,可以通過調(diào)用EnterCriticalSection函數(shù)申請進入臨界區(qū)。由于同一時間內(nèi)只能有一個線程進入臨界區(qū),所以在申請的時候如果有一個線程已經(jīng)進入臨界區(qū),則該函數(shù)就會一直等到那個線程執(zhí)行完臨界區(qū)代碼;

(3)離開臨界區(qū);當執(zhí)行完臨界區(qū)代碼后,需要調(diào)用LeaveCriticalSection函數(shù)離開臨界區(qū);

(4)刪除臨界區(qū);當不需要臨界區(qū)時調(diào)用DeleteCriticalSection函數(shù)將臨界區(qū)對象刪除;

下面的代碼創(chuàng)建了5個線程,每個線程在文件中寫入10000個“hello”:

#include <stdio.h> #include <windows.h> HANDLE hFile; CRITICAL_SECTION cs;//定義臨界區(qū)全局變量 //線程函數(shù):在文件中寫入10000個hello DWORD WINAPI Thread(LPVOID lpParam) {int n = (int)lpParam;DWORD dwWrite;for (int i = 0;i < 10000;i++){//進入臨界區(qū)EnterCriticalSection(&cs);char data[512] = "hello\r\n";//寫文件WriteFile(hFile, data, strlen(data), &dwWrite, NULL);//離開臨界區(qū)LeaveCriticalSection(&cs);}printf("Thread #%d returned successfully\n", n);return 0; } int main() {char *filename = "hack.txt";WCHAR name[20] = { 0 };MultiByteToWideChar(CP_ACP, 0, filename, strlen(filename) + 1, name, sizeof(name) / sizeof(name[0]));//創(chuàng)建文件hFile = CreateFile(name, 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];//初始化臨界區(qū)InitializeCriticalSection(&cs);for (int i = 0;i < 5;i++){//創(chuàng)建線程,并調(diào)用Thread寫文件hThread[i] = CreateThread(NULL, 0, Thread, (LPVOID)(i + 1), 0, &ThreadID);printf("Thread #%d has been created successfully.\n", i + 1);}//等待所有進程結(jié)束WaitForMultipleObjects(5, hThread, TRUE, INFINITE);//刪除臨界區(qū)DeleteCriticalSection(&cs);//關(guān)閉文件句柄CloseHandle(hFile);return 0; } 結(jié)果如圖:


總結(jié)

以上是生活随笔為你收集整理的使用CreateThread函数创建线程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。