大家对进程以及线程的概念一定不陌生:进程-系统资源分配的最小单位;线程-系统调度的最小单位;不过今天要说的是另一个比较新的概念:纤程。
在早期的计算机系统中,只有进程概念,数据资源和调度都以进程为单位,但是对于系统调度而言进程的体量太大了,效率很低;这个时候线程应运而生,线程的出现解决了系统的调度问题;当然线程也有着一定的缺陷:1.抢占式调度;2.调度发生在内核态;纤程的出现就是为了应对纤程的这两个缺陷;纤程的调度运行在用户态,且由用户控制不可抢占;
在windows下使用纤程有如下几个步骤:
1.创建主纤程:ConvertThreadToFiber();通过接口的名称可以看出这个接口的作用是将线程转换为纤程,也可说是启动线程的纤程模式;
2.创建子纤程:CreateFiber();通过这个接口可以创建一个子纤程,但是并不执行;
3.纤程的调度:SwitchToFiber();通过调用此接口,可以让程序停止当前的执行,跳转到指定纤程的最后一个执行状态;
4.纤程的删除:DeleteFiber();同其他系统资源相同,纤程使用完成后需要调用API进行删除;
注意:
1.同一个主纤程下的各个子纤程之间是串行执行的;
2.子纤程其实是在主纤程所在的线程中进行执行;
3.可以依赖goto(虽然现在几乎没什么人用了)语句进行帮助理解;
说了一些可能也没怎么说清楚,直接上代码吧!
// 运行环境 win7 vs2017
#include <stdio.h>
#include <windows.h>
#define PRODUCER 0
#define CONSUMER 1
int data;
LPVOID pc_fiber[2];
// 生产者函数
void __stdcall producer(LPVOID param)
{
int counter = 0;
int sum = *(int *)param;
while (counter++ < sum)
{
// 每五秒生产一次数据
Sleep(500);
data = rand();
printf("producer finished producing, the data is %d.\n", data);
// 跳转到消费者纤程
SwitchToFiber(pc_fiber[CONSUMER]);
}
}
// 消费者函数
void __stdcall consumer(LPVOID param)
{
while (1)
{
printf("consumer get the data of %d.\n\n", data);
// 完成数据消费,跳转到生产者纤程
SwitchToFiber(pc_fiber[PRODUCER]);
}
}
int main()
{
// 创建主纤程
ConvertThreadToFiber(NULL);
int count = 5;
// 创建生产者纤程
pc_fiber[PRODUCER] = CreateFiber(0, producer, &count);
// 创建消费者纤程
pc_fiber[CONSUMER] = CreateFiber(0, consumer, 0);
// 开始生产者纤程
SwitchToFiber(pc_fiber[PRODUCER]);
// 开始消费者纤程
SwitchToFiber(pc_fiber[CONSUMER]);
// 纤程清理
DeleteFiber(pc_fiber[PRODUCER]);
DeleteFiber(pc_fiber[CONSUMER]);
return 0;
}