C/C++ _beginthreadex 多线程操作

使用beginthreadex函数实现C++多线程 需要注意的是,在访问g_count变量时,我们使用了EnterCriticalSection和LeaveCriticalSection函数来保证线程安全,同时需要先调用InitializeCriticalSection函数初始化临界区,最后使用DeleteCriticalSection函数删除临界区。在上面的代码中,我们定义了一个名为g_count的全局变量作为计数器,然后使用beginthreadex函数创建了5个线程,并让它们分别执行ThreadFunc函数。 阅读详情
AI摘要

本文详细介绍了C/C++中线程的创建方法,包括使用_beginthreadex、CreateThread及C++11 thread的不同方式,并探讨了多线程同步问题。

最近主管没有分配任务,于是将C/C++的线程学习一下。

经过了解才知道,C++03之前,用的创建线程都是CreateThread 与 _beginthreadex。使用这个两个函数进行创建线程。
然后C++11之后,就出现了新的线程函数thread,当然,这个创建线程比较方便!

经过两三天的纠结,最终决定深入研究_beginthreadex此方式创建线程,具体为什么我也说不清楚,看到网上很多人都推荐使用这个。。。

反正_beginthreadex内部都是调用CreateThread 进行创建线程的!



一、概念

简单说一下概念。

进程是包含线程的,一个进程可以有多个线程,多个线程(或一个)组合成一个进程。

线程是CPU调度和分派的基本单位,进程是分配资源的基本单位。

一个应用程序就是一个进程,例如运行一个QQ,运行一个微信等等,都是一个进程。
在QQ里面,我一边接收文件,一遍与别人聊天,这就是两个线程在同时运行!
在这里插入图片描述

为什么使用多线程

  1. 避免阻塞
    大家知道,单个进程只有一个主线程,当主线程阻塞的时候,整个进程也就阻塞了,无法再去做其它的一些功能了。
  2. 避免CPU空转
    应用程序经常会涉及到RPC,数据库访问,磁盘IO等操作,这些操作的速度比CPU慢很多,而在等待这些响应时,CPU却不能去处理新的请求,导致这种单线程的应用程序性能很差。
  3. 提升效率
    一个进程要独立拥有4GB的虚拟地址空间,而多个线程可以共享同一地址空间,线程的切换比进程的切换要快得多。

在这里插入图片描述

头文件:
#include < process.h >


二、_beginthreadex创建线程

_beginthreadex
这里我们使用这个函数创建线程!

函数参数如下:

unsigned long _beginthreadex(
  
    void *security,    		// 安全属性, 为NULL时表示默认安全性
 
    unsigned stack_size,    // 线程的堆栈大小, 一般默认为0
 
    unsigned(_stdcall *start_address)(void *),   // 线程函数
 
    void *argilist, 		// 线程函数的参数
 
    unsigned initflag,    	// 新线程的初始状态,0表示立即执行,//CREATE_SUSPENDED表示创建之后挂起
   
    unsigned *threaddr    	// 用来接收线程ID
 
);

返回值 : 成功返回新线程句柄, 失败返回0

创建线程:

int iParam = 10;
unsigned int dwThreadID;	// 接收线程的ID
HANDLE hThread;				// 线程句柄

// 创建线程
hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, (void *)&iParam, 0, &dwThreadID);


// 线程执行的函数
unsigned int WINAPI  ThreadFun(LPVOID p) {

	int cnt = *((int *)p);
	// ......

	return 0;
}

第一第二个参数,默认写NULL和0就行了,第三个参数是线程执行的函数,第四个参数是函数的参数,第五个参数是指定线程立刻执行,第六个参数是获得线程的ID。

可以判断一下线程句柄,是否创建线程成功:

if (hThread == NULL) {
	printf("_beginthreadex() Error!\n");
	return -1;
}

如果函数需求是传入多个参数,那么只能使用结构体了!

然后线程执行完毕后要记得关闭线程句柄:

CloseHandle(hThread);

到此,一个简单的线程就已经创建完毕了!

测试代码:

#include <stdio.h>
#include <Windows.h>
#include <process.h>

unsigned int WINAPI  ThreadFun(LPVOID p) {

	int cnt = *((int *)p);
	for (int i = 0; i < cnt; i++) {
		Sleep(1000);
		printf("Running thread!\n");
	}

	return 0;
}

int main(void) {
	int iParam = 10;
	unsigned int dwThreadID;	// 线程id

	printf("main begin\n");

	// 线程句柄				// 创建线程
	HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, (void *)&iParam, 0, &dwThreadID);

	if (hThread == NULL) {
		printf("_beginthreadex() Error!\n");
		return -1;
	}
	
	// 关闭
	CloseHandle(hThread);

	printf("main end\n");
	//Sleep(5000);
	system("pause");
	return 0;
}

在这里插入图片描述

注意:
代码中必须加上 system(“pause”);让主线程暂停在哪里等待子线程执行完毕,否则主线程执行完毕就直接接收程序了,子线程完全没有机会执行!
这里的mian函数就是主线程也就是进程,当进程结束后,会结束掉所有线程!

如下截图:
在这里插入图片描述


三、单线程句柄阻塞

上面第二点,如果我想等子线程执行完了之后再接着继续往下走执行printf(“main end\n”);
这需要怎么操作呢?

这就要用到阻塞了,就是阻塞主线程,子线程执行完毕后,再接着执行主线程。

使用这个函数:
WaitForSingleObject:等待一个内核对象变为已通知状态

WaitForSingleObject(
    _In_ HANDLE hHandle,    	  //指明一个内核对象的句柄
    _In_ DWORD dwMilliseconds     //等待时间
);

这样使用:

DWORD wr;
	
// 等待通知,等待子线程执行完毕
// 阻塞主线程,INFINITE:等待特定秒数;WAIT_FAILED:WaitForSingleObject等待结束后会返回它
printf("WaitForSingleObject() begin\n");
if ((wr = WaitForSingleObject(hThread, INFINITE)) == WAIT_FAILED) {
	printf("Thread wait error!\n");
	return -1;
}
printf("WaitForSingleObject() end\n");

WaitForSingleObject传入两个参数,参数一是线程句柄,参数二是等待时间,INFINITE表示很多秒,具体多少秒不知道,但是足以应付日常线程使用,也可以指定具体秒数。
如果发生错误会返回WAIT_FAILED,这样进行判断就可以知道等待是有没有发生错误了!

测试代码:

#include <stdio.h>
#include <Windows.h>
#include <process.h>

// 线程执行的函数
unsigned int WINAPI  ThreadFun(LPVOID p) {

	int cnt = *((int *)p);
	for (int i = 0; i < cnt; i++) {
		Sleep(1000);
		printf("Running thread!\n");
	}

	return 0;
}

int main(void) {
	int iParam = 10;
	unsigned int dwThreadID;	// 线程id
	DWORD wr;	// 阻塞线程返回值

	printf("main begin\n");

	// 线程句柄				// 创建线程
	HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, (void *)&iParam, 0, &dwThreadID);

	if (hThread == NULL) {
		printf("_beginthreadex() Error!\n");
		return -1;
	}

	// 等待通知,等待子线程执行完毕
	// 阻塞主线程,INFINITE:等待特定秒数;WAIT_FAILED:WaitForSingleObject等待结束后会返回它
	printf("WaitForSingleObject() begin\n");
	if ((wr = WaitForSingleObject(hThread, INFINITE)) == WAIT_FAILED) {
		printf("Thread wait error!\n");
		return -1;
	}
	printf("WaitForSingleObject() end\n");

	CloseHandle(hThread);

	printf("main end\n");
	//Sleep(5000);
	//system("pause");	// 不需要再暂停了
	return 0;
}

在这里插入图片描述


四、多个线程句柄阻塞

提一个需求,创建n个线程,然后循环n次,奇数次对一个全局变量做加一操作,偶数次对一个全局变量做减一操作。
按照正常来讲,设置这个全局变量为零,当程序结束,这个全局变量也还是零才对,事实上是这样嘛?

使用WaitForMultipleObjects阻塞多个线程

WaitForMultipleObjects(
    _In_ DWORD nCount,    		// 要监测的句柄的组的句柄的个数
    _In_reads_(nCount) CONST HANDLE* lpHandles,   //要监测的句柄的组
    _In_ BOOL bWaitAll,  		// TRUE 等待所有的内核对象发出信号, FALSE 任意一个内核对象发出信号
    _In_ DWORD dwMilliseconds 	//等待时间
);

使用如下:

// 阻塞多个线程句柄,直到子线程运行完毕,主线程才会往下走
WaitForMultipleObjects(NUM_THREAD, tHandles, TRUE, INFINITE);

参数一:检测句柄的个数;参数二:检测句柄的数组;参数三:TRUE等待所有线程执行完毕,FALSE,任意一个完成就停止阻塞;参数四:等待时间

测试代码:

#include <stdio.h>
#include <Windows.h>
#include <process.h>

#define NUM_THREAD		50

unsigned WINAPI threadInc(void *arg);	// 减一操作
unsigned WINAPI threadDes(void *arg);	// 加一操作

// 操作的全局变量
long long num = 0;

int main(void) {
	// 创建n个线程句柄
	HANDLE tHandles[NUM_THREAD];
	
	printf("sizeof long long :%d\n", sizeof(long long));

	// 循环n次,创建n个线程
	for (int i = 0; i < NUM_THREAD; i++) {
		if (i % 2) {
			tHandles[i] = (HANDLE)_beginthreadex(NULL, 0, threadInc, NULL, 0, NULL);
		
		} else {
			tHandles[i] = (HANDLE)_beginthreadex(NULL, 0, threadDes, NULL, 0, NULL);
		}
	}

	// 阻塞多个线程句柄,直到子线程运行完毕,主线程才会往下走
	WaitForMultipleObjects(NUM_THREAD, tHandles, TRUE, INFINITE);

	for (int i = 0; i < NUM_THREAD; i++) {
		CloseHandle(tHandles[i]);
	}

	printf("result:%lld\n", num);
	return 0;
}


// 对全局变量加一操作
unsigned WINAPI threadInc(void *arg) {
	for (int i = 0; i < 500000; i++) {
		num += 1;
	}

	return 0;
}


// 对全局变量减一操作
unsigned WINAPI threadDes(void *arg) {
	for (int i = 0; i < 500000; i++) {
		num -= 1;
	}

	return 0;
}

在这里插入图片描述
可以看到,最终结果不是零,而是乱值,这是为什么???

在这里插入图片描述

以上图为例,假设全局变量num是99,线程一开始执行,获取它做加一操作,然后还没等线程一将数值还回去,线程二又获取它做操作,然后还回去,最后线程一才将数值还回去,所以导致计算结果不正确。
这里这是举一个例子啊,大致上表达的意思就是线程一和线程二公用同一块内存变量,导致数值计算不正确。

如果想要解决这个问题,那么必须使用:互斥对象CreateMutex,这个将在下一篇博客中讲解用法!


五、CreateThread创建线程

CreateThread是一种微软在Windows API中提供了建立新的线程的函数,该函数在主线程的基础上创建一个新线程。线程终止运行后,线程对象仍然在系统中,必须通过CloseHandle函数来关闭该线程对象。

HANDLE CreateThread(
	LPSECURITY_ATTRIBUTES lpThreadAttributes,//SD
	SIZE_T dwStackSize,//initialstacksize
	LPTHREAD_START_ROUTINE lpStartAddress,//threadfunction
	LPVOID lpParameter,//threadargument
	DWORD dwCreationFlags,//creationoption
	LPDWORD lpThreadId//threadidentifier
)

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

测试代码:

#include <stdio.h>
#include <Windows.h>
#include <process.h>

DWORD WINAPI ThreadFun(LPVOID p) {
	double d = *((double *)p);

	printf("我是子线程, PID = %d\nd = %f\n", GetCurrentThreadId(), d);
	return 0;
}

int main(void) {

	HANDLE hThread;
	DWORD dwThreadID;
	double p = 3.14;

	hThread = CreateThread(NULL, 0, ThreadFun, &p, 0, &dwThreadID);
	printf("我是主线程, PID = %d\n", GetCurrentThreadId());

	// 关闭线程
	CloseHandle(hThread);

	Sleep(2000);
	system("pause");
	return 0;
}

在这里插入图片描述


六、thread创建线程

#include <iostream>
#include <thread>
#include <Windows.h>

using namespace std;

void print1() {
	Sleep(3000);
	cout << "子线程1在运行。。。" << endl;
}

void print2() {
	Sleep(3000);
	cout << "子线程2在运行。。。" << endl;
}



class testThread {
public:
	testThread() {
	// 这是一种重要用法,我在项目中常用
		t1 = new thread(&testThread::test, this);
		t1->detach();
		t2 = new thread(&testThread::test, this);
		t2->join();
	}

	~testThread() {
		if (t1) delete t1;
		if (t2) delete t2;
	}

	void test() {
		for (int i = 0; i < 10; i++) {
			cout << "正在运行:" << i << endl;
			Sleep(1000);
		}
	}

private:
	thread *t1;
	thread *t2;
};




int main(void) {

	// 创建线程
	thread test1(print1);
	thread test2(print2);

	// join函数,汇合线程,阻塞主线程,等待子线程执行结束,才会回到主线程中
	test1.join();

	// detch函数,分离,打破与主线程的依赖关系,即主线程运行主线程,子线程运行子线程,两个互不干扰
	test2.detach();

	cout << "主线程在运行..." << endl;


	// joinable函数,判断当前线程是否可以做join或者detach过程,可以返回true,不可以返回false.
	if (test2.joinable()) {
		test2.join();
	
	} else {
		cout << "子线程不可以做join或detch操作" << endl;
	}

	return 0;
}

七、总结

线程的创建就是这么简单,当然,可以根据自己的项目需求,有针对性的去学习哪一种线程,效果都是一样的!

Windows C++多线程:使用_beginthreadex 本文介绍了C++多线程技术中的_beginthreadex函数,以及与_createThread函数的区别。本文将介绍起始线程函数_createThread和_beginthreadex的区别,并通过实例演示如何使用_beginthreadex创建多线程。它们都可以用来创建新的线程,但是二者的使用方式略有不同,_beginthreadex更加方便和安全。而_beginthreadex可以接收多个参数,且可以设置线程的堆栈大小和安全属性,使线程更加安全。最后,等待线程结束,关闭句柄,程序运行结束。 阅读详情

相关推荐

多线程编程在C++中的使用:_beginthread函数

注意,在实际的多线程编程中,还需要考虑线程的安全性、死锁等问题,并采取相应的措施进行处理。在C++中,可以使用互斥量(mutex)来实现线程之间的同步,并使用全局变量或线程局部存储(Thread Local Storage,TLS)来实现数据的共享。头文件,然后定义了线程函数,使用_beginthread函数创建线程,并在主函数中等待线程结束。在使用_beginthread函数创建线程之前,我们需要定义一个线程函数。一旦我们定义了线程函数,就可以使用_beginthread函数来创建线程。

CodeGu的博客 533

秒杀多线程第二篇 多线程第一次亲密接触 CreateThread与_beginthreadex本质区别

本文将带领你与多线程作第一次亲密接触,并深入分析CreateThread与_beginthreadex的本质区别,相信阅读本文后你能轻松的使用多线程并能流畅准确的回答CreateThread与_beginthreadex到底有什么区别,在实际的编程中到底应该使用CreateThread还是_beginthreadex? 使用多线程其实是非常容易的,下面这个程序的主线程会创建了一个子线程并等待...

huobengluantiao8 3585

国科GK7202V300芯片开发避坑指南:从uboot编译到SDK配置的12个实战问题解决

本文针对国科GK7202V300芯片开发过程中的常见难题,提供从uboot编译、SDK配置到系统部署的实战解决方案。详细解析了开发环境搭建、内核编译、驱动模块加载、根文件系统构建及烧写部署等12个关键环节的避坑指南,帮助开发者高效解决编译错误、配置冲突等典型问题,提升开发效率。

sunny的博客 233

c++多线程之_beginthreadex

创建一个线程,具体用法查看代码 ,特别注意: 如果在代码中有使用标准C运行库中的函数时,尽量使用_beginthreadex()来代替CreateThread() 因为_beginthreadex在内部调用了CreateThread,在调用之前_beginthreadex做了很多的工作,从而使得它比CreateThread更安全。 例子一 #include <windows.h&g...

sinat_31608641的博客 5503

二、PCIE的TLP包的封包解包原理

熟悉 PCIE 的组建包的过程,以及内部的字段细节的定 义,掌握如何发送接收 Mrd(memory read TLP)、 Mwr(Memory write TLP)、Cpl (Completion TLP)和 Cpld(Completion with data TLP)命令包,深入理解 PCIE 底层协议工作过程

k7126685的博客 3928

华为擎云W515 PGUV-WBY0安装银河麒麟V10全流程解析

本文详细解析了华为擎云W515 PGUV-WBY0安装银河麒麟V10系统的全流程,包括准备工作、镜像下载与校验、启动盘制作、BIOS设置、安装过程关键选择、系统初始化及常见问题排查。特别针对ARM架构设备提供了实用技巧,帮助用户顺利完成国产化系统的部署与优化。

weixin_28725949的博客 696

C++ 使用_beginthreadex创建线程、线程句柄(等待线程关闭)、线程id的作用(发送线程消息)

_beginthreadex c语言库 process.h 中的函数, 用来创建一个线程 unsignedlong_beginthreadex( void*security,//安全属性,为NULL时表示默认安全性 unsignedstack_size,//线程的堆栈大小,一般默认为0 ...

qq_24127015的博客 1万+

GPU加速的容器化AI开发:AnolisOS/CentOS8中的NVIDIA驱动与CUDA最佳实践

本文详细介绍了在AnolisOS/CentOS8系统中配置NVIDIA驱动与CUDA的最佳实践,涵盖驱动安装、CUDA工具链配置、容器运行时设置及性能优化等关键步骤。特别针对容器化AI开发场景,提供了GPU透传和资源管理的实用方案,帮助开发者构建高效的GPU加速开发环境。

weixin_27791839的博客 339

C++多线程——_beginthread()和_beginthreadex

转载自:https://blog.youkuaiyun.com/lyzyung/article/details/38513563 https://blog.youkuaiyun.com/xuanyin235/article/details/77689512 一、背景介绍 ★两套API :OS API vs CRT API   首先,Windows操作系统本身提供了线程的创建函数CreateThread 和销毁函数...

m0_37350758的博客 3563

DFT实战:如何用Synopsys工具搞定多时钟域Scan Chain设计(附避坑指南)

本文详细解析了使用Synopsys DFT Compiler工具链实现多时钟域Scan Chain设计的全流程,包括时钟混合策略、跨时钟域平衡技巧和实战脚本剖析。通过量产验证的工程实践方案,帮助DFT工程师有效解决复杂SoC设计中的Scan Chain挑战,提升测试效率和质量。

mm9012的博客 1031

别再花屏了!手把手教你用STM32CubeIDE搞定LVGL 8.3移植(附完整源码)

本文详细介绍了如何在STM32CubeIDE环境下成功移植LVGL 8.3,解决常见的花屏问题。从环境配置、显示驱动优化到编译警告处理,提供完整的实战方案和源码示例,帮助开发者快速实现流畅的嵌入式GUI界面。特别针对STM32平台的DMA2D加速和内存管理进行了深度优化。

weixin_33739646的博客 241

C/C++ _beginthreadex 多线程操作 - 线程同步

互斥对象、事件对象、信息量、关键代码段、线程死锁

cpp_learner的博客 1810

基于STM32的录音机设计(STM32F103+VS1053B)

本项目设计并实现了一款基于STM32微控制器的便携式录音机。该录音机采用STM32F103C8T6作为主控芯片,结合VS1053B音频编解码模块、SD卡存储、OLED显示屏以及按键模块,提供了手动录音、自动录音和录音回放等多种功能。

1万+

C++系列 --- 操作系统乱序推进线程指令的本质剖析

C/C++运行期库 1、概念 在实际的开发过程中,一般使用C/C++运行期函数_beginthreadex代替CreateThread函数。 _beginthreadex首先申请一些用于线程同步的变量,然后调用CreateThread 需要用#include <process.h>头文件 同样,使用_endthreadex代替ExitThread。该函数首先释放用于线程同步...

平凡 265

三菱FX5U系列PLC与汇川IT6000系列触摸屏进行MODBUS TCP通信的具体方法

三菱FX5U系列PLC与汇川IT6000系列触摸屏进行MODBUS TCP通信的具体方法

Robot_PLC_HMI_Automation 6513

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

多线程学习笔记

1、如果在代码中有使用标准C运行库中的函数时,尽量使用_beginthreadex()来代替CreateThread()。 2、在多线程环境中对一个变量进行读写时,我们需要有一种方法能够保证对一个值的递增操作是原子操作——即不可打断性,一个线程在执行原子操作时,其它线程必须等待它完成之后才能开始执行该原子操作,Windows系统为我们提供了一些以Interlocked开头的函数来完成这...

angtuanv07384的博客 107

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C++多线程(二)

<br />C/C++ Runtime 多线程函数<br /><br />一 简单实例<br />主线程创建2个线程t1和t2,创建时2个线程就被挂起,后来调用ResumeThread恢复2个线程,使其开始执行,调用WaitForSingleObject等待2个线程执行完,然后推出主线程即结束进程。<br /> <br />/* file Main.cpp * * This program is an adaptation of the code Rex Jaeschke showed in

dylan的专栏 648

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C++多线程

C/C++ Runtime 多线程函数 一 简单实例(来自codeprojct:http://www.codeproject.com/useritems/MultithreadingTutorial.asp) 主线程创建2个线程t1和t2,创建时2个线程就被挂起,后来调用ResumeThread恢复2个线程,是其开始执行,调用WaitForSingleObject等待2个线程执行完,然后推

mniwc的专栏 1707

CreateThread、_beginthreadex和AfxBeginThread .

创建线程好几个函数可以使用,可是它们有什么区别,适用于什么情况呢?参考了一些资料,写得都挺好的,这里做一些摘抄和整合。 【参考1】CreateThread, AfxBeginThread,_beginthread, _beginthreadex的区别====================================================================...

aolan7349的博客 193

vtk 编译遇到 “_beginthreadex”: 找不到标识符

用VC ++ 6.0编写控制台程序,出现错误提示如下,错误提示:nafxcwd.lib(thrdcore.obj):错误LNK2001:无法解析的外部符号__endthreadex nafxcwd.lib(thrdcore.obj):错误LNK2001:无法解析的外部符号__beginthreadex libcd.lib(crt0.obj):错误LNK2001:无法解析的外部符号_main 调试/...

deeplan_1994的博客 1722

6 - 线程

之前介绍了进程是由两个部分构成的,一个是进程内核对象,另一个是地址空间。同样,线程也是由两个部分组成的: • 一个是线程的内核对象,操作系统用它来对线程实施管理。内核对象也是系统用来存放线程统计信息的地方。 • 另一个是线程堆栈,它用于维护线程在执行代码时需要的所有函数参数和局部变量 。 如果想要创建一个或多个辅助函数,只需要让一个已经在运行的线程来调用C r e a t e

whbsxx1314的专栏 310

windows环境编程: 线程创建函数 设置线程名 隐藏DOS窗口 重定向IO

_beginthreadex是微软的C/C++运行时库函数,CreateThread是操作系统的函数。 _beginthreadex通过调用CreateThread来实现的,但比CreateThread多做了许多工作。 注意:若要创建一个新线程,绝对不要使用CreateThread,而应使用_beginthreadex.            Why?

鸟窝 2556

_beginThreadex创建多线程解读

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _beginThrea

weixin_43418664的博客 204

windows多线程详解

在一个牛人的博客上看到了这篇文章,所以就转过来了,地址是http://blog.youkuaiyun.com/morewindows/article/details/7421759 本文将带领你与多线程作第一次亲密接触,并深入分析CreateThread与_beginthreadex的本质区别,相信阅读本文后你能轻松的使用多线程并能流畅准确的回答CreateThread与_beginthreadex到底有什

心如止水-GISer的成长之路 6万+

多线程编程示例1(结合实例)

1.CreateThread与_beginthreadex #pragma once #include<cstdio> #include<Windows.h> #include<crtdbg.h> #include<process.h> //子线程函数 DWORD WINAPI ThreadFun1(LPVOID ...

160
上一篇: Linux + Qt :探讨QT直接调用JS方法传参的问题
下一篇: C/C++ _beginthreadex 多线程操作 - 线程同步
cpp_learners
博客等级 码龄7年 1526粉丝 274原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值