1. 程式人生 > >C++多執行緒系列(一)CreateThread和_beginthreadex區別

C++多執行緒系列(一)CreateThread和_beginthreadex區別

現在在學習多執行緒,順便將蒐集到的資料整理下來以供參考和查詢。

首先在開始多執行緒學習的時候遇到的首要問題便是多執行緒的建立,在查閱資料後有CreateThread和_beginthreadex兩種方法,可能不止這兩種,以後學習到了再補充。

----------------------------------------------20160914更新-------------------------------------------------

在建立新的執行緒時一定要使用_beginthreadex函式而不要使用CreateThread函式,因為CreateThread函式對系統中的全域性變數沒有保護,所以多個執行緒環境下容易出現系統的全域性變數的值被覆蓋的情況,而_beginthreadex每個執行緒都有單獨的系統全域性變數入errno.

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

(1)CreateThread

HANDLE
WINAPI
CreateThread(
    _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,		//執行緒的安全屬性,NULL則為預設屬性
    _In_ SIZE_T dwStackSize,								//指定執行緒堆疊大小,NULL則預設堆疊大小
    _In_ LPTHREAD_START_ROUTINE lpStartAddress,				//執行緒函式其實地址及執行執行緒的函式
    _In_opt_ __drv_aliasesMem LPVOID lpParameter,			//傳遞給執行緒函式的引數
    _In_ DWORD dwCreationFlags,								//指定執行緒建立後是否立即執行,若0則表示執行緒立即執行
    _Out_opt_ LPDWORD lpThreadId
    );

lpThreadAttributes,是一個執行SECURITY_ATTRIBUTES結構的指標,如果需要預設安全屬性則傳遞引數NULL,
 如果希望此執行緒物件控制代碼可以被子程序繼承的話,必須設定一個SECURITY_ATTRIBUTES的機構,將它的bInheritHandle成員初始化為TRUE

如下:

SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.IpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;     //使CreateThread返回的控制代碼可以被繼承

HANDLE handle = CreateThread(&sa,...);

dwCreationFlags,建立標誌,如果是0表示執行緒被建立後立即開始執行,如果指定為CREATE_SUSPENDED標誌,表示執行緒被建立以後處於掛
 起狀態,直到使用ResumeThread顯式啟動執行緒為止。

#include <stdio.h>
#include <windows.h>
//子執行緒函式
DWORD WINAPI ThreadFun(LPVOID pM)
{
	printf("子執行緒的執行緒ID號為:%d\n子執行緒輸出Hello World\n", GetCurrentThreadId());
	return 0;
}
//主函式,所謂主函式其實就是主執行緒執行的函式。
int main()
{
	HANDLE handle = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL);
	WaitForSingleObject(handle, INFINITE);
	return 0;
}

其中DWORD:unsigned long; WINAPI:_stdcall; LPVOID:void *

(2)_beginthreadex函式

在C/C++標準執行庫裡面有許多的全域性變數入errno、strerror等,他們可以用來表示執行緒當前的狀態。但是在多執行緒設計中每個執行緒必須有唯一的狀態,佛則這些變數記錄的資訊準確度無法保證。如下程式碼所示

if (system("notepad.exe readme.txt") == -1)
	{
		switch(errno)
		{
			....//程式處理錯誤程式碼
		}
	}


加入某個執行緒A執行上面的程式碼,在執行system後,還未來得及呼叫switch()函式,這時執行緒B同樣執行該程式碼出錯,並將錯誤代號寫入全域性變數errno中,這樣,A一旦開始執行swtich()時,它所訪問的程式碼並不是本身錯誤程式碼而是執行緒B賦予的錯誤程式碼。像strerror()、strtok()、tmpnam()、gmtime()、asctime()等函式也會遇到這種由於多個執行緒訪問修改導致的資料覆蓋問題。

為了避免此類情況發生,Windows作業系統提供了標準執行庫函式 _beginthreadex,讓執行期設定了相關變數後再去呼叫Windows系統提供的CreateThread函式。_beginthreadex的引數與CreateThread函式是對應的,只是引數名和型別完全不同,使用的時候需要進行強制轉化。_beginthreadex函式定義如下:

_ACRTIMP uintptr_t __cdecl _beginthreadex(
    _In_opt_  void*                    _Security,
    _In_      unsigned                 _StackSize,
    _In_      _beginthreadex_proc_type _StartAddress,
    _In_opt_  void*                    _ArgList,
    _In_      unsigned                 _InitFlag,
    _Out_opt_ unsigned*                _ThrdAddr
    );


引數含義與CreateThread函式是對應的。例項程式碼如下:
#include <stdio.h>
#include <process.h>
#include <windows.h>
//子執行緒函式
unsigned int __stdcall ThreadFun(PVOID pM)
{
	printf("執行緒ID號為%4d的子執行緒說:Hello World\n", GetCurrentThreadId());
	return 0;
}
//主函式,所謂主函式其實就是主執行緒執行的函式。
int main()
{
	const int THREAD_NUM = 5;
	HANDLE handle[THREAD_NUM];
	for (int i = 0; i < THREAD_NUM; i++)
		handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, NULL, 0, NULL);
	WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
	return 0;
}

參考教材:《Windows程式設計第三版》-張錚

相關推薦

C++執行系列CreateThread_beginthreadex區別

現在在學習多執行緒,順便將蒐集到的資料整理下來以供參考和查詢。首先在開始多執行緒學習的時候遇到的首要問題便是多執行緒的建立,在查閱資料後有CreateThread和_beginthreadex兩種方法,可能不止這兩種,以後學習到了再補充。-------------------

java執行系列:Thread、Runnable、Callable實現執行區別

實現多執行緒 java實現多執行緒的方法有三種,分別是繼承thread類,實現runnable介面,實現callable介面(call方法有返回值) /** * 繼承Thread */ public class MyThread extends Thread{ int a = 0;

C++執行系列執行互斥

首先了解一下執行緒互斥的概念,執行緒互斥說白了就是在程序中多個執行緒的相互制約,如執行緒A未執行完畢,其他執行緒就需要等待! 執行緒之間的制約關係分為間接相互制約和直接相互制約。 所謂間接相互制約:一個系統中的多個執行緒必然要共享某種系統資源如共享CPU,共享印表機。間接制

java執行系列基礎概念

前言 這一系列多執行緒的文章,一方面是個人對Java現有的多執行緒機制的學習和記錄,另一方面是希望能給不熟悉Java多執行緒機制、或有一定基礎但理解還不夠深的讀者一個比較全面的介紹,旨在使讀者對Java的多執行緒有一個遞增、全面和較深刻的理解,所以在第一部分就集中介紹一

C#執行程式設計程序與執行

一、 程序         簡單來說,程序是對資源的抽象,是資源的容器,在傳統作業系統中,程序是資源分配的基本單位,而且是執行的基本單位,程序支援併發執行,因為每個程序有獨立的資料,獨立的堆疊空間。一個程式想要併發執行,開多個程序即可。

執行系列執行基礎

執行緒相關概念 在學習多執行緒之前,先來了解下幾個與多執行緒相關的概念。 程序:程序是計算機的概念,程式在伺服器執行時佔據全部計算資源的總和,一個應用程式執行起來就是一個程序,開啟windows的工作管理員,如下圖 執行緒:執行緒也是計算機的概念,執行緒是程序的最小單位,也是程式在響應作業系統時的最小單位

C++執行系列C++11-uniqu_lock

Data 2018/11/12 Add By  WJB 在多執行緒中,有時候會出現一個方法中又一斷或者多段程式碼需要加鎖,但是並非整個方法程式碼加鎖,那麼我們就需要一個靈活的鎖-unique_lock;說明:unique_lock會降低程式碼執行效率,不推薦使用。 我們接

c++11執行程式設計:建立執行的三種方法

c++11執行緒庫原始的c++標準僅支援單執行緒程式設計,新的c++標準(c++11或c++0x)於2011年釋出,引入了新的執行緒庫。 編譯器要求 Linux: gcc 4.8.1 (完全併發支援) Windows: Visual Studio 2012 and Min

java執行-初探

啥是多執行緒?跟程序又是啥關係?   比方說:我去洗手,洗完手去吃飯。 程序(Processor) 洗手跟吃飯是兩個程序。 執行緒(Thread) 在洗手的程序裡,我同時聽歌,還唱歌。那這裡洗手是一個程序,聽歌跟唱歌是兩個執行緒。 在吃飯的程序裡,我同時聽歌,還

簡單的Linux C++執行CLOCK時鐘

剛剛加入CSDN部落格,初來乍到也不知道寫什麼,所以來分享一個自己以前學C++的時候寫的第一個類,一個關於時鐘的簡單的Linux多執行緒CLOCK(時鐘)類: /***********************************************

執行基礎

最近讀了高洪巖的《Java多執行緒程式設計核心技術》一書,打算記錄下多執行緒的基礎知識點,也算對本書的一個讀後感了。目前打算分四五篇博文進行記錄。 第一篇主要是記錄執行緒的概念,建立,常用的基礎方法等。 1. 什麼是執行緒? 通常我們所說執行緒是程序的最小單位。那麼問題來了,什麼是程序呢?程序就是作業系統結構

C++ 執行框架 2:Mutex 互斥 Sem 訊號量

互斥和訊號量是多執行緒程式設計的兩個基礎,其原理就不詳細說了,大家去看看作業系統的書或者網上查查吧。 對於互斥的實現,無論什麼作業系統都離不開三個步驟 1.初始化互斥鎖 2.鎖操作 3.解鎖操作 對於不同的系統只是實現的函式有一些不同而已,但是功能其實都大同小異,在

C++ 執行框架1:new 一下就啟動一個執行

幾年前寫過一個C++的多執行緒框架,雖然寫完了,但是人一懶做了一次說明以後就沒影了,最近把程式碼整理了一下,準備發到github上,在這裡,再把這個框架總結一下吧。 多執行緒一直是程式設計中常見的問題,特別是在Linux的c++上,多執行緒的封裝一直不是很好,當然,

C++ 執行框架3:訊息佇列

之前,多執行緒一些基本的東西,包括執行緒建立,互斥鎖,訊號量,我們都已經封裝,下面來看看訊息佇列 我們儘量少用系統自帶的訊息佇列(比如Linux的sys/msgqueue),那樣移植性不是很強,我們希望的訊息佇列,在訊息打包和提取都是用的標準的C++資料結構,當然,

執行程式設計——寫一個簡單的死鎖

(整個九月忙著找工作,好多收穫,好多遺憾,最終結局還可以接受,技術路還很遠,再接再厲!面去哪兒網時,寫慣了演算法的我突然讓寫了幾個多執行緒程式設計,有點矇蔽,最近好好整理一下) 死鎖發生的原因: 1、

Linux 執行程式設計

Linux 多執行緒程式設計 執行緒(Thread)已被許多作業系統所支援,包括Windows/NT ,Linux 以前的多執行緒其實是多程序,而現在意味著一個程序中有多個執行緒 使用多執行緒的原因(多執行緒的優點): 1.“節省”,啟動一個新的程序需要分配給它獨立的地

執行系列---執行個鎖

多個執行緒多個鎖:多個執行緒,每個執行緒都可以拿到自己指定的鎖,分別獲得鎖之後,執行synchronized方法體內容。 關鍵字synchronized取得的鎖都是物件鎖,而不是把一段程式碼(方法)當

執行學習執行的兩種實現方式

程序和執行緒 程序是受作業系統管理的基本執行單元。 執行緒是在程序中獨立執行的子任務。 多執行緒的優點 使用多執行緒技術後,可以在同一時間內執行更多不同種類的任務。 單執行緒是同步執行任務,多執行緒是非同步執行任務。 多執行緒的使用方式 1:繼承Thread 2:實現

Java執行學習Java執行入門

Java 併發的基礎知識,可能會在筆試中遇到,技術面試中也可能以併發知識環節提問的第一個問題出現。比如面試官可能會問你:“談談自己對於程序和執行緒的理解,兩者的區別是什麼?” 一 程序和多執行緒簡介 1.1 程序和執行緒 程序和執行緒的對比這一知識點

執行理解  三大特性

程序、執行緒和多執行緒的定義。 程序:是指一段具有某種獨立功能的程式關於某個資料集合的一次執行活動(一段程式的執行過程)。 執行緒:單個程序執行中的每個任務就是一個執行緒。 多執行緒:在一個程序中有多個執行緒共享程序資源,執行任務。 多執行緒的三大特性: 原子性: