C++多线程编程学习(1):

多线程编程学习(1)

1.创建一个线程
开关线程的API函数:

HANDLE CreateThread(
	LPSECURITY_ATTRIBUTES lpThreadAttributes,	//SD:线程安全属性,常置为NULL
	SIZE_T dwStackSize,				//initialstacksize:初始化栈的大小,可设置为0
	LPTHREAD_START_ROUTINE lpStartAddress,		//threadfunction:线程函数
	LPVOID lpParameter,				//threadargument:传入线程函数的参数,一般指向结构体,不需传递参数时为NULL
	DWORD dwCreationFlags,				//creationoption:线程属性,没有需要时置0
	LPDWORD lpThreadId				//threadidentifier:线程ID,如果为NULL则不返回线程ID
)
BOOL WINAPI CloseHandle(HANDLE hObject);            //关闭线程

//----------------------------------------------------------------------------------------------------------------------------------------------
子线程函数体的调用格式:
DWORD WINAPI 函数名 (LPVOID lpParam)//在正常的函数体前加DWORD WINAPI,否则无法调用
//----------------------------------------------------------------------------------------------------------------------------------------------
接下来看一个代码,例子:

#include <iostream>
#include <windows.h>

using namespace std;

DWORD WINAPI multthread(LPVOID lpargs)
{
	for (int i = 0; i < 10; i++)
	{
		cout << i << "   son  "<<endl; Sleep(200);
	}
	return 0;
}
	
int main()
{
	int aa = 10;
	HANDLE H1 = CreateThread(NULL, 0, multthread, NULL, 0, NULL);//创造一个线程
	for (int i = 0; i < aa;i++)
	{
		cout << i << "   parent  "<<endl; Sleep(200);
	}
	CloseHandle(H1);
	return 0;
}

从输出的结构来看,主程序和子线程已经交替的进行了输出:
在这里插入图片描述
但是,主线程和子线程的输出,为什么有时候在同一行,或者是空一行------
这是由于子线程和主线程在输出时,还未输出endl换行,子线程就抢先输出了,所以出现这种情况。
cout << i << " son "<<endl; Sleep(200);
换成:
cout << i << " son \n"; Sleep(200);

输出结果为:
在这里插入图片描述
2.还有一种方法可以解决上述输出问题,加一个互斥锁,保证某个线程能够独占资源
API函数为:

HANDLE WINAPI CreateMutex(
	LPSECURITY_ATTRIBUTES lpMutexAttributes,        //安全属性,常置为NULL
	BOOL                  bInitialOwner,            //创建Mutex时的当前线程是否拥有Mutex的所有权
	LPCTSTR               lpName                    //Mutex的名称)
	
DWORD WINAPI WaitForSingleObject(
	HANDLE hHandle,					//要获取的锁的句柄
	DWORD  dwMilliseconds                           //超时间隔,为INFINITE则表示无限等待
	);
	
BOOL WINAPI ReleaseMutex(HANDLE hMutex);		//释放

例子:

#include <iostream>
#include <windows.h>

using namespace std;
HANDLE H2 = NULL;//********************************************

DWORD WINAPI multthread(LPVOID lpargs)
{
	for (int i = 0; i < 10; i++)
	{
		WaitForSingleObject(H2, INFINITE);//********************************
		cout << i << "   son  "<<endl; Sleep(200);
		ReleaseMutex(H2);//************************************
	}
	return 0;
}
	
int main()
{
	int aa = 10;
	HANDLE H1 = CreateThread(NULL, 0, multthread, NULL, 0, NULL);//创造一个线程
	H2 = CreateMutex(NULL, FALSE, NULL);//创建互斥锁***********************
	for (int i = 0; i < aa;i++)
	{
		WaitForSingleObject(H2, INFINITE);//*********************
		cout << i << "   parent  "<<endl; Sleep(200);
		ReleaseMutex(H2);//******************************
	}
	CloseHandle(H1);
	return 0;
}

在这里插入图片描述
3.单个和多个参数的传入
下面代码向子线程中传入了一个int型的数,传入方式如下:
在这里插入图片描述
输出结果为:主程序运行完后,等待子线程运行结束。
在这里插入图片描述
5. 传入结构体
在这里插入图片描述
输出结果:
在这里插入图片描述
6.线程调用类中的函数

#include <thread>
#include <chrono>
#include <iostream>
using namespace std;
class thread_c
{
public:
	void add_(int aa,int bb)
	{
		cout << "hello from class member function" <<aa<<"   "<<bb<< endl;
	}
private:
};
int main()
{
	thread_c  c;
	thread t(&thread_c::add_,c,50,30);//类名+成员函数,实例化的类,输入的参数
	this_thread::sleep_for(chrono::milliseconds(100));
	t.detach();//线程后台运行
	//t.join();//等待线程运行完后退出
	return 0;
}
传入结构体
#include <thread>
#include <chrono>
#include <iostream>
using namespace std;
struct par
{
	int aa;
	int bb;
};
class thread_c
{
public:
	void add_(par parm)
	{
		cout << "hello from class member function" <<parm.aa<<"   "<<parm.bb<< endl;
	}
private:
};
int main()
{
	par parm;
	parm.aa = 50;
	parm.bb = 30;
	thread_c  c;
	thread t(&thread_c::add_,c,parm);
	this_thread::sleep_for(chrono::milliseconds(100));
	t.detach();
	return 0;
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值