2021/10/31 paradigm 笔记

自用 paradigm笔记
摘要由CSDN通过智能技术生成

1 并行概念

问题:怎么让1个应用程序中的2个“函数”看起来好像是同时在运行呢?
—— 线程;
问题:怎么让2个“应用程序”看起来好像是在同一个处理器中同时运行呢?
—— 进程;

1.1 虚拟地址空间

虚拟:指的是对于每个应用程序来说,它的地址空间自己看上去好像是无限宽广

1.1.1 进程的概念

实际上,同一时间,只有1个CPU,只有1个寄存器组!

在这里插入图片描述

MMU的作用:将每个应用程序的“虚拟地址”映射到真正的“物理地址”上!通过MMU我们将1个处理器,编程多个“假的处理器”!

1.1.2 线程的概念

在这里插入图片描述

多线程的作用:让1个程序里面的多个函数一起跑起来!!!

各个线程以“轮转”的方式平等占用处理器一段时间(这个时间可能是100 ms)。

示例:售票员问题

问题:假设的售票大厅共有10个售票员,150张票,请模拟10个售票员同时售卖150张票的情形!

模拟代码(非并行):

void SellTickets(int agentID, int numTicketsToSell)
{
   
	while(numTicketsToSell > 0) {
   
		printf("Agent %d sells a ticket\r\n", agentID),
		numTicketsToSell--;
	}
	printf("Agent %d: All Down\r\n", agentID);
}

int main()
{
   
	uint8_t agent;
	int numAgents = 10; // 10个售票员
	int numTickets = 150; // 150 张票
	
	for(agent = 0; agent < numAgents; agent++) {
   
		SellTickets(agent, numTickets / numAgents);
	}
	return 0;
}

预计结果:160行printf输出!这些票是从第0位售票员开始,依次到第1位售票员、第2位售票员……第9位售票员,1张1张地卖出去的,并不是10个售票员同时售票!!!这样做,10个人弄得跟1个人一样!!!效率太低了!!!

我们肯定希望,10个售票员同时往出买票。

需求:需要寻找1个线程库,来帮助你实现“线程”!

2 windows下的多线程

多线程的意义在于,1个线程在被阻塞的时候,另1个线程还可以运行!你想想啊,最开始学单片机的时候,有个叫“软件延时的”,这是纯粹消耗机器周期以进行延时。在“软件延时”的过程中,CPU干不了别的事情,它只能在那里干等着!这不是浪费资源嘛!

2.1 C的 <process.h> 与 <windows.h>

<process.h>

序号 函数名 功能
1 _beginthread() 创建1个新线程(简洁版)
2 _endthread() 销毁1个线程(简洁版)
3 _beginthreadex() 创建1个新线程(全面版)
4 _endthreadex() 销毁1个线程(全面版)

<windows.h>

序号 函数名 功能
1 ResumeThread() 恢复线程的运行
2 SuspendThread() 挂起线程
3 GetExiCodeThread() 得到1个线程的退出码
4 WaitForSingleObject() 等待1个对象
5 WaitForMultipleObjects() 等待多个对象

2.1.1 创建线程的方法

<process.h> 中提供了2种创建线程的方式!1个简洁版本的 _beginthread(),这个获取不了子线程的ID号;另1个是全面版本的 _beginthreadex(),这个可以获取子线程的ID号!!!

2.1.1.1 _beginthread() 原型
_CRTIMP uintptr_t __cdecl _beginthread(void (__cdecl *_StartAddress) (void *),
									unsigned int _StackSize,
									void *_ArgList);
  • 第1个参数 *_StartAddress
    你要执行的函数入口地址(名字);
  • 第2个参数 _StackSize
    分配给这个线程的栈大小,默认0(1MB);
  • 第3个参数 *_ArgList
    传递给线程的参数列表,无参时写NULL;
  • 返回值
    成功则返回新线程的句柄,失败则返回0
2.1.1.2 _beginthreadex() 原型
_CRTIMP uintptr_t __cdecl _beginthreadex(void *_Security,
										unsigned int _StackSize,
										unsigned int (__stdcall *_StartAddress) (void *),
										void *_ArgList,
										unsigned int _InitFlag,
										unsigned int *_ThrdAddr);
  • 第1个参数 *_Security
    安全属性,默认NULL;
  • 第2个参数 _StackSize
    分配给这个线程的栈大小,默认0(1MB);
  • 第3个参数 *_StartAddress
    你要执行的函数地址(名字)
  • 第4个参数 *_ArgList
    函数入参列表
  • 第5个参数 _InitFlag
    新线程的初始状态,0表示立即执行,CREATE_SUSPENDED 表示挂起
  • 第6个参数 *_ThrdAddr
    用来传出线程的ID号
  • 返回值
    成功则返回新线程的句柄,失败则返回0
示例:运行1个线程
例1:使用简洁的 _beginthread()
typedef struct tag_paramStruct {
   </
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值