C++多線程筆記整理(二)

上一節中,是單獨的把線程函數和主函數放到了一起,不太符合類的封裝。這一節把多線程放到一個類裏面,然後在主函數中調用這個類以及多線程。多線程,需要定義爲靜態成員函數,如果裏面涉及到參數,也應該定義爲靜態成員變量。

頭文件, *.h

#include <Windows.h>
#include <iostream>
using namespace std;

class Test
{
public:
	Test();
	~Test();
	static int add(int b);
	static DWORD WINAPI thread1(LPVOID lpParameter);
	static DWORD WINAPI thread2(LPVOID lpParameter);
private:
	static int a;
	static int c;
};
static CRITICAL_SECTION th1, th2;

源文件, *.cpp

#include "StaticThread.h"

int Test::a = 10;    // 靜態成員變量,需要這樣進行初始化
int Test::c = 10;
Test::Test()
{
	InitializeCriticalSection(&th1);    // 用線程鎖之前,一定要初始化
	InitializeCriticalSection(&th2);
}

Test::~Test()
{
	DeleteCriticalSection(&th1);        // 用完以後,要釋放
	DeleteCriticalSection(&th2);
}

int Test::add(int b)  // 形參
{
	return a + b;
}

DWORD WINAPI Test::thread1(LPVOID lpParameter)
{
	while(true)
	{
		EnterCriticalSection(&th1);
		if (a < 50)
		{
			Sleep(1);// 交出權限,讓下一個線程執行
			cout << "thread1: a = " << a++ << endl;
		}
		else
			break;
		LeaveCriticalSection(&th1);
	}
	return 0;
}

DWORD WINAPI Test::thread2(LPVOID lpParameter)
{
	while(true)
	{
		EnterCriticalSection(&th2);
		if (c < 50)
		{
			Sleep(1);// 交出權限,讓上一個線程執行
			cout << "thread2: c = " << c++ << endl;	
		}
		else
			break;
		LeaveCriticalSection(&th2);
	}
	return 0;
}

主文件, main.cpp

#include<iostream>
using namespace std;

int main()
{
	Test t;

	HANDLE ht_1, ht_2;
	ht_1 = CreateThread(NULL, 0, t.thread1, NULL, 0, NULL);// 需要注意,調用多線程的方式
	ht_2 = CreateThread(NULL, 0, t.thread2, NULL, 0, NULL);
	CloseHandle(ht_1);
	CloseHandle(ht_2);

	Sleep(300);// 讓主函數等待線程運行完
	cout << "main thread" << endl;
	
	system("pause");
	return 0;
}

運行結果如下: 可以看到,開頭輸出的 1線程,被2線程打斷了,導致 a 沒有完全輸出,就開始輸出 c。之後的話就比較均勻了。

線程中Sleep(1), 主要是爲了讓線程停止一下,把控制權交出去。上面代碼例子中,是對兩個變量,分別在各自線程中,在各自的CPU核上運行,所以互不干擾。

 

     

運行多次,發現,這種輸出,是不太可控的,有時候a先輸出,有時候,輸出到一半,被停下。

推測,是CPU分配任務比較智能(或者隨機)導致的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章