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