最近因为工作的需要,写了1个线程池,线程这个东西,并不难,但是在多线程情况下,遇到的挑战是不同于以往的。
首先,为什么要用多线程,很简单,效率至上。在windows平台上,进程必须依赖线程执行,也就是说,进程必须要有根主线程。创建线程的开销要远小于进程的开销。在创建进程时,系统要为进程分配一大串的信息,比如内存啥的。线程的开销分为创建,执行和销毁,其中执行的开销由程序员来控制,也就是具体的执行逻辑。那么假如不停的开辟线程和销毁线程,而做的是同样的工作,消耗仍然很大,那怎么办,开辟一次就够了,让线程不停的等待任务来临再执行,执行玩继续等待。那么假如工作了n次,就省去了n-1次的开辟和销毁的时间。怎么做呢,我写的模型大概是这样的:
while(1)
{
等待工作信号;
信号来了,从任务池取任务并执行逻辑;
重置信号;
}
这样的模型又涉及到信号什么时候来,那么必须有一根捕捉任务输入的线程,而这根线程可一刻都不能闲着,因为随时可能要有任务
while(1)
{
Sleep(1);
检测是否有任务,有则把任务放进任务池;
设置信号;
}
由于线程的并发性,上面的两种线程同时用到了任务池这个资源,这就带来了问题。所有的程序最终都会编译成汇编再到机器代码才能执行,一个取任务的逻辑翻译到汇编的话恐怕不止一条汇编指令吧,如果取任务的线程还没执行完取的过程而CPU暂停它的执行继而执行放任务的线程的逻辑,那将是灾难,怎么办,还好系统提供了一种原子操作的东西和一种临界区的概念,如果一个线程进入了临界区,那么其他线程想要进入这个临界区时,它将会被阻塞,这可是个好东西啊。可能我说的并不是很清楚,可以去看<windows核心编程>这本书,作者是位高人。
上面的模型只是个粗略的框架,关于多线程,还有好多东西要去学习,我水平有限,希望大家不要笑话我,呵呵~