Aplicación simple de subprocesos múltiples C ++

1. El primer resumen de subprocesos múltiples de C++ Aquí solo resumimos el uso de std::thread y CreateThread, y los artículos posteriores actualizarán el uso completo. Para facilitar la escritura, todas las explicaciones de uso se escriben en los comentarios del código. No hay muchas tonterías, solo ve al código.

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <thread>
#include <string>
#include <windows.h>
#include <mutex>

//声明全局互斥量对象做线程同步
std::mutex mutexx;
//声明全局临界区对象做线程同步
CRITICAL_SECTION cs;
//结构体
struct MyStruct
{
    
    
	const std::string content;
	const int id;
};
void show1(const char str[], const int id)
{
    
    
	mutexx.lock();
	std::cout << "测试函数1线程: " << id << ",Output " << str << std::endl;
	Sleep(100);//必须包含#include <windows.h>才可以使用Sleep
	mutexx.unlock();
}

void show2(const char str[])
{
    
    
	EnterCriticalSection(&cs);
	std::cout << "测试函数2线程: " << ",Output " << str << std::endl;
	Sleep(500);
	LeaveCriticalSection(&cs);
}


DWORD WINAPI show3(LPVOID lpargs)
{
    
    
	EnterCriticalSection(&cs);
	MyStruct *p = (MyStruct *)lpargs;//转换为结构体指针
	std::cout << p->content << ",ID: " << p->id  << std::endl;
	Sleep(2000);
	LeaveCriticalSection(&cs);
	return 0;
}

//利用std::thread创建线程
void test1()
{
    
    
	//这种创建线程的方式,当线程创建完成,就会立马执行线程函数。
	//可以传递一个或者多个参数,std::thread t1(“函数名”, "函数参数1", “函数参数2”)
	//t1.join(); //表示同步(阻塞),调用线程走完,才能走后面的流程
	//t1.detach(); //表示异步(不会阻塞),主线程只触发此线程,后面和此线程无关
	std::thread t1(show1, "hello cplusplus!", 1);
	std::thread t2(show1, "你好,C++!", 2);
	std::thread t3(show1, "hello!", 3);
	t1.join(); t2.join(); t3.join();
	//t1.detach(); t2.detach(); t3.detach();
	std::cout << "测试函数1线程,一共三个线程全部执行完毕 " << std::endl;
	//调用t1.join(); t2.join(); t3.join();后
	//代码运行到这里,证明声明的三个线程已经全部运行完毕,后面代码可以综合三个线程的结果,执行后面的判断
}

//利用CreateThread创建线程
void test2()
{
    
    
	//注释:
	//这种创建线程的方式,当线程创建完成,可以选择立马执行或者先挂起后面再唤醒线程执行。
	//CreateThread默认只能传递一个参数。如果需要多个参数,可以声明函数时,传入结构体。
	//CreateThread的返回值是线程的句柄, 失败的话就返回NULL

	//CreateThread函数原型
	//HANDLE CreateThread(

	//	LPSECURITY_ATTRIBUTES lpThreadAttributes,

	//	DWORD dwStackSize,

	//	LPTHREAD_START_ROUTINE lpStartAddress,

	//	LPVOID lpParameter,

	//	DWORD dwCreationFlags,

	//	LPDWORD lpThreadID

	//);
	//第一个参数 lpThreadAttributes 表示线程内核对象的安全属性,一般传入NULL表示使用默认设置。
	//第二个参数 dwStackSize 表示线程栈空间大小。传入0表示使用默认大小(1MB)。
	//第三个参数 lpStartAddress 表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址。
	//第四个参数 lpParameter 是传给线程函数的参数。
	//第五个参数 dwCreationFlags 指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()。
	//第六个参数 lpThreadId 将返回线程的ID号,传入NULL表示不需要返回该线程ID号。


	//测试单个线程执行
	HANDLE hThread;
	DWORD threadId;
	MyStruct struct1{
    
    "单个线程执行传递多个参数的线程函数",1};
	hThread = CreateThread(NULL, 0, show3, &struct1, 0, &threadId);

	//注释:
	// WaitForSingleObject("线程句柄",“等待时间(单位ms)”)
	//WaitForSingleObject在等待时间内,线程执行完成,则返回0,否则返回值大于0
	//等待时间如果设置为INFINITE,则会阻塞直到对应线程执行完成。等待时间如果设置为0,则不会阻塞直接运行后续代码。如果设置1000,则线程阻塞1000ms后,执行后续代码。
	DWORD ret;
	ret = WaitForSingleObject(hThread, 2500);
	CloseHandle(hThread);
	std::cout << "单个线程全部执行完毕。 " << "规定时间内线程运行完成与否:" << ret << std::endl;
	//代码运行到这里,证明声明的三个线程已经全部运行完毕,后面代码可以综合三个线程的结果,执行后面的判断
	//*******************************************************************************************************************************


	//*******************************************************************************************************************************
	//测试多线程并发
	//注释:
	//DWORD WaitForMultipleObjects(

	//	DWORD nCount,             // number of handles in the handle array
	//	CONST HANDLE *lpHandles,  // pointer to the object-handle array
	//	BOOL fWaitAll,            // wait flag
	//	DWORD dwMilliseconds      // time-out interval in milliseconds
	//);
	//参数解析:
	//	DWORD 就是 Double Word, 每个word为2个字节的长度,DWORD双字即为4个字节,每个字节是8位。
	//	nCount  指定列表中的线程句柄数量  最大值为MAXIMUM_WAIT_OBJECTS(64)
	//	*lpHandles 线程句柄数组的指针(数组)。lpHandles为指定对象句柄组合中的第一个元素 HANDLE类型可以为(Event,Mutex,Process,Thread,Semaphore)数组
	//	bWaitAll 等待的类型,如果为TRUE,表示除非所有对象都发出信号(所有都执行完成),否则就一直等待下去;如果FALSE,表示任何一个对象发出信号即可
	//	dwMilliseconds指定要等候的毫秒数。如设为零,表示立即返回。如指定常数INFINITE,则可根据实际情况无限等待下去
	//WaitForMultipleObjects在等待时间内,线程执行完成,则返回0,否则返回值大于0
	const int thNum = 5;
	HANDLE hThread2[thNum];
	DWORD threadId2[thNum];
	for (int i = 0; i < thNum; i++)
	{
    
    
		MyStruct struct2{
    
     "多线程并发执行传递多个参数的线程函数",i };
		hThread2[i] = CreateThread(NULL, 0, show3, &struct2, 0, &threadId2[i]);
	}
	DWORD ret2;
	ret2 = WaitForMultipleObjects(thNum, hThread2, true, 100);
	for (int i = 0; i < thNum; i++)
	{
    
    
		CloseHandle(hThread2[i]);
	}
	std::cout << "多个线程并发全部执行完毕。 " << "规定时间内线程运行完成与否:" << ret2 << std::endl;
	//代码运行到这里,证明声明的三个线程已经全部运行完毕,后面代码可以综合三个线程的结果,执行后面的判断
}
int main()
{
    
    
	//初始化临界区对象
	//CRITICAL_SECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用
	InitializeCriticalSection(&cs);

	//多线程同步测试
	test1();
	test2();

	//清除临界区对象,释放资源
	DeleteCriticalSection(&cs);
	system("pause");
}

Supongo que te gusta

Origin blog.csdn.net/Douhaoyu/article/details/128683417
Recomendado
Clasificación