windows线程库

本文介绍了Windows系统中创建线程的基本方法CreateThread,详细解析了函数参数和使用示例,展示了多线程环境下同步问题及其解决办法。此外,还提及了进程关闭的相关概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 CreateThread

1. 函数原型:


    HANDLE WINAPI CreateThread(
      _In_opt_  LPSECURITY_ATTRIBUTES  lpThreadAttributes,   
      _In_      SIZE_T                 dwStackSize,
      _In_      LPTHREAD_START_ROUTINE lpStartAddress,
      _In_opt_  LPVOID                 lpParameter,
      _In_      DWORD                  dwCreationFlags,
      _Out_opt_ LPDWORD                lpThreadId
    );

2. 参数说明:

  • 第一个参数 lpThreadAttributes 表示线程内核对象的安全属性,一般传入NULL表示使用默认设置。

  • 第二个参数 dwStackSize 表示线程栈空间大小。传入0表示使用默认大小(1MB)。

  • 第三个参数 lpStartAddress 表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址。

  • 第四个参数 lpParameter 是传给线程函数的参数。

  • 第五个参数 dwCreationFlags 指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()。

  • 第六个参数 lpThreadId 将返回线程的ID号,传入NULL表示不需要返回该线程ID号。

3.返回值

线程创建成功返回新线程的句柄,失败返回NULL

 4.实例

#include <Windows.h>
#include <iostream> 
using namespace std;
int n=0;
DWORD WINAPI getMsg(LPVOID lpParam)
{
    n++;
    cout<<"执行子线程"<<n<<endl;
	return 0;
}
 
 
int main()
{
	int count=5;
	while(count--){
	    DWORD threadID;
	    HANDLE hThread;
 
	    hThread = CreateThread(NULL,0,getMsg,NULL,0,&threadID);
 
	    cout<<"执行主线程1!"<<endl;
	    //Sleep(1);
	    cout<<"执行主线程2!"<<endl;	
	}
	return 0;
}

输出结果 有多种情况

在多次循环中创建了五个子线程。可以很明显的看出主线程和子线程之间不同步对输出的影响。(换行情况比较混乱)

 

接下来让情况更加复杂一点。在子线程中继续创建子线程。

#include <Windows.h>
#include <iostream> 
using namespace std;
int n=0;
DWORD WINAPI getMsg(LPVOID lpParam)
{
    n++;
    cout<<"执行子线程"<<n<<endl;
    DWORD threadID;
	HANDLE hThread;
 
	hThread = CreateThread(NULL,0,getMsg,NULL,0,&threadID);
	return 0;
}
 
 
int main()
{
	int count=5;
	while(count--){
	    DWORD threadID;
	    HANDLE hThread;
 
	    hThread = CreateThread(NULL,0,getMsg,NULL,0,&threadID);
 
	    cout<<"执行主线程1!"<<endl;
	    //Sleep(1);
	    cout<<"执行主线程2!"<<endl;	
	}
	return 0;
}

依旧可以看出,多个子线程之间不同步造成的影响。 

同时多个线程访问临界值n时,因为线程调度的不可控性,导致可能多个线程先后都是从内存上取到的0,这样自加后的结果与实际结果会不一致。为了避免这种情况,就需要原子操作InterlockedExchangeAdd(g_nVal, 1)
 

LONG InterLockedIncrement(
  LPLONG lpAddend // variable address  //使++成为原子操作
  );
LONG InterlockedDecrement(
  LPLONG lpAddend // variable address  //使--成为原子操作
  );

二.关闭进程

// 结束线程调用,终止自己
VOID WINAPI ExitThread(
  __in DWORD dwExitCode	  // 线程结束时的退出码
);

// 由当前线程终止其他线程
BOOL WINAPI TerminateThread(
  __in_out HANDLE hThread,  // 终止的线程句柄
  __in DWORD dwExitCode     // 退出码
);

// 进程退出
VOID WINAPI ExitProcess(
  __in UINT uExitCode   // 退出码
);

void _endthreadex( 
   unsigned retval     // 退出码 
);

_in_out,_in,_out为空宏,不参与编译和运算,仅起到提示作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值