带你深入浅出之Windows编程:三、左青龙右白虎,两个常用线程创建函数

此为Windows编程的第谈!关注我,带你快速通过Windows编程的学习路线

每一篇的技术点都是很很重要!很重要!很重要!但不冗余!

我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点!

码农不易,各位学者学到东西请点赞支持支持

开始部分:

总:

首先,我们要了解线程的概念:

操作系统就类似一个工厂

线程是CPU调度和分配的基本单位。(工人);

进程是分配资源的基本单位,正在运行的程序。(就是一个车间,可以有多个工人)。

分:

左青龙:Createthread()函数

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程的安全属性
  DWORD dwStackSize,                       // 线程栈的大小
  LPTHREAD_START_ROUTINE lpStartAddress,   // 线程函数的起始地址
  LPVOID lpParameter,                      // 传递给线程函数的参数
  DWORD dwCreationFlags,                    // 线程的创建标志
  LPDWORD lpThreadId                       // 线程标识符的地址
);
  1. lpThreadAttributes:指向SECURITY_ATTRIBUTES结构的指针,用于设置线程的安全属性。如果不需要特殊安全属性,可以传递NULL

  2. dwStackSize:指定新线程的栈大小,以字节为单位。如果设置为0,将使用默认的栈大小

  3. lpStartAddress:指向线程函数的指针,这是新线程执行的起始点。它应该是一个返回DWORD并接受单个LPVOID类型参数的函数。

  4. lpParameter传递给线程函数的参数。这个参数将被转换为LPVOID类型,并作为ThreadFun函数的p参数。

  5. dwCreationFlags线程的创建标志。常用的标志有CREATE_SUSPENDED(创建并挂起线程,需要手动使用ResumeThread函数恢复执行)和0(立即执行线程)

  6. lpThreadId:指向DWORD变量的指针,用于接收新创建线程的标识符。如果不需要线程标识符,可以传递NULL

示例代码:

#include <stdio.h>
#include <thread>
#include <windows.h>

DWORD WINAPI ThreadFun(LPVOID p) {
	int iMym = *((int*)p);
	printf("我是子线程,PID=%d,iMym = %d\n", GetCurrentThreadId(), iMym);
	return 0;
}


int main()
{
	printf("main begin\n");
	HANDLE hThread;
	DWORD dwThreadID;
	int m = 100;
	hThread = CreateThread(NULL, 0, ThreadFun, &m, 0, &dwThreadID);
	printf("我是主线程,PID = %d\n", GetCurrentThreadId());
	CloseHandle(hThread);
	Sleep(2000);
	system("pause");
	return 0;
}

执行结果:

右白虎:_beginthreadex()函数

unsigned int _beginthreadex(
  void* security,  // 线程的安全属性,通常为NULL
  unsigned stack_size,  // 线程的栈大小,通常为0,使用默认大小
  unsigned (__stdcall* start_address)(void*),  // 线程函数的入口点
  void* arglist,  // 传递给线程函数的参数
  unsigned initflag,  // 线程的初始化标志,通常为0
  unsigned* thrdaddr  // 接收新创建线程的标识符的指针
);
  1. security:指向SECURITY_ATTRIBUTES结构的指针,用于设置线程的安全属性。通常设置为NULL

  2. stack_size:指定新线程的栈大小。如果设置为0,将使用默认的栈大小

  3. start_address指向线程函数的指针,该函数应符合unsigned int (__stdcall *)(void *)的签名,即无参数,返回unsigned int

  4. arglist传递给线程函数的参数,通常是一个指向数据的指针。

  5. initflag线程的初始化标志。如果设置为0,线程将立即执行。其他值(如CREATE_SUSPENDED)可以控制线程的初始状态。

  6. thrdaddr:指向unsigned int变量的指针,用于接收新创建线程的标识符

示例代码:

#include <stdio.h>
#include <windows.h>
#include <thread>
unsigned WINAPI thread_main_hong(void* arg)
{
	int cnt = *((int*)arg);
	for (int i=0;i<cnt;i++)
	{
		printf("俯卧撑\n");
		Sleep(3000);
	}
	return 0;
}

unsigned WINAPI thread_main_ming(void* arg)
{
	int cnt = *((int*)arg);
	for (int i = 0; i < cnt; i++)
	{
		printf("跳舞\n");
		Sleep(3000);
	}
	return 0;
}

unsigned WINAPI thread_main_wang(void* arg)
{
	int cnt = *((int*)arg);
	for (int i = 0; i < cnt; i++)
	{
		printf("唱歌\n");
		Sleep(3000);
	}
	return 0;
}




int main()
{
	int xiaohong = 20, xiaoming = 30, laowang = 50;

	unsigned int hong_id, ming_id, wang_id;
    //三个线程都是随机执行的
	_beginthreadex(NULL, 0, &thread_main_hong, (void*)&xiaohong, 0, &hong_id);
	_beginthreadex(NULL, 0, &thread_main_ming, (void*)&xiaoming, 0, &ming_id);
	_beginthreadex(NULL, 0, &thread_main_wang, (void*)&laowang, 0, &wang_id);
	Sleep(100000);
	system("pause");
	return 0;
}

执行结果:

总:对于创建线程函数,学会这两个常用的即可。线程的执行其实就是把函数放入,变成线程执行。

   学习链接:https://xxetb.xetslk.com/s/3Kif2D

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值