此为Windows编程的第三谈!关注我,带你快速通过Windows编程的学习路线!
每一篇的技术点都是很很重要!很重要!很重要!但不冗余!
我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点!
码农不易,各位学者学到东西请点赞支持支持!
开始部分:
总:
首先,我们要了解线程的概念:
操作系统就类似一个工厂;
线程是CPU调度和分配的基本单位。(工人);
进程是分配资源的基本单位,正在运行的程序。(就是一个车间,可以有多个工人)。
分:
左青龙:Createthread()函数
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程的安全属性
DWORD dwStackSize, // 线程栈的大小
LPTHREAD_START_ROUTINE lpStartAddress, // 线程函数的起始地址
LPVOID lpParameter, // 传递给线程函数的参数
DWORD dwCreationFlags, // 线程的创建标志
LPDWORD lpThreadId // 线程标识符的地址
);
-
lpThreadAttributes
:指向SECURITY_ATTRIBUTES
结构的指针,用于设置线程的安全属性。如果不需要特殊安全属性,可以传递NULL
。 -
dwStackSize
:指定新线程的栈大小,以字节为单位。如果设置为0,将使用默认的栈大小。 -
lpStartAddress
:指向线程函数的指针,这是新线程执行的起始点。它应该是一个返回DWORD
并接受单个LPVOID
类型参数的函数。 -
lpParameter
:传递给线程函数的参数。这个参数将被转换为LPVOID
类型,并作为ThreadFun
函数的p
参数。 -
dwCreationFlags
:线程的创建标志。常用的标志有CREATE_SUSPENDED
(创建并挂起线程,需要手动使用ResumeThread
函数恢复执行)和0(立即执行线程)。 -
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 // 接收新创建线程的标识符的指针
);
-
security
:指向SECURITY_ATTRIBUTES
结构的指针,用于设置线程的安全属性。通常设置为NULL
。 -
stack_size
:指定新线程的栈大小。如果设置为0,将使用默认的栈大小。 -
start_address
:指向线程函数的指针,该函数应符合unsigned int (__stdcall *)(void *)
的签名,即无参数,返回unsigned int
。 -
arglist
:传递给线程函数的参数,通常是一个指向数据的指针。 -
initflag
:线程的初始化标志。如果设置为0,线程将立即执行。其他值(如CREATE_SUSPENDED
)可以控制线程的初始状态。 -
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;
}
执行结果:
总:对于创建线程函数,学会这两个常用的即可。线程的执行其实就是把函数放入,变成线程执行。