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分配任务比较智能(或者随机)导致的。

发布了417 篇原创文章 · 获赞 156 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_34732729/article/details/105439395