如何实现进程池

如何实现进程池


http://blog.csdn.net/guosha/article/details/3874998 这是原作者链接 感谢作者分享

有位站友问,如何在linux下实现进程池技术,原贴见:
http://topic.csdn.net/u/20090206/16/b424e1c1-90dc-4589-a63f-1d90ed6560ae.html

之前虽对进程池这个名词早有耳闻,但一直没有真正接触过。乍一听好像有点复杂,但稍微一想却也简单,下面我就按自己的想法来实现一个简单的模型。

 

跟最简单的资源管理一样,进程池技术的应该致少由以下两部分组成

资源进程
预先创建好的空闲进程,管理进程会把工作分发到空闲进程来处理。

管理进程
管理进程负责创建资源进程,把工作交给空闲资源进程处理,回收已经处理完工作的资源进程。

 

上面资源进程跟管理进程的概念很好理解,下面就是进程池的关键,管理进程如何有效的管理资源进程,如何分配任务给资源进程,如何回收空闲资源进程。其实稍加分析一下也很简单,管理进程要有效的管理资源进程,那么管理进程跟资源进程间必然需要交互,如何交互呢?linux下两个进程如何交互?IPC呗,信号,信号量,消息队列,管道,随便选一个合适的就可以了。


下面我就用信号加消息队列来完成上面帖子里的进程池需求。

  1. //主接收网络消息进程  
  2. int main()  
  3. {  
  4.     int iReLen;  
  5.     char szBuffer[64];  
  6.     ...  
  7.     //初始化进程池  
  8.     InitProcessPoll();  
  9.     ....  
  10.     while(1)  
  11.     {  
  12.         iRelen = recv(iSock, szBuffer, sizeof(szbuffer), 0);  
  13.         if (iRelen > 0)  
  14.         {  
  15.             SubmitWork(szBuffer, iRelen);   //提交工作到资源进程  
  16.         }     
  17.     }  
  18.     ...  
  19. }  
  20.   
  21. //  
  22. int SubmitWork(void *pBuffer, int iMsgLen)  
  23. {  
  24.     int iMsgQueID;  
  25.       
  26.     iMsgQueID = GetMsgQue(key, 0); //取得跟管理进程通信的消息队更句柄;  
  27.       
  28.     msgsnd(iMsgQueID, pBuffer, iMsgLen, 0);  
  29. }  
  30.   
  31. int InitProcessPoll(const int iProcessNum)  
  32. {  
  33.     int iPid;  
  34.       
  35.     //创建管理进程  
  36.     iPid = fork();  
  37.     if (iPid == 0)  
  38.     {  
  39.         InitMngProcess(iProcessNum);  
  40.     }     
  41.     return 0;  
  42. }  
  43.   
  44. typedef struct  
  45. {  
  46.     int pid;  
  47.     int iFlag;  
  48. } T_ProcessStatus;  
  49.   
  50. //指向资源进程管理结构  
  51. T_ProcessStatus *pProcessMng = NULL;  
  52.   
  53. //记录有总共有多少个资源进程  
  54. INT32 iMaxProcessNum = 0;  
  55.   
  56. //初始管理进程管理结构并创建资源子进程,最后接收外部工作请求并分发到资源进行进行处理  
  57. InitMngProcess(const int iProcessNum)  
  58. {  
  59.     int i;  
  60.     int iPid;  
  61.     int iRtn;  
  62.     int iMsgLen;  
  63.     int iMsgQue1, iMsgQue2;  
  64.     char szBuffer[64];  
  65.       
  66.     //创建管理进程结构  
  67.     pProcessMng = calloc(iProcessNum, sizeof(T_ProcessStatus))  
  68.   
  69.     for (i = 0; i < iProcessNum; i++)  
  70.     {  
  71.         iPid = fork();  
  72.         if (iPid == 0);  
  73.         {  
  74.             //资源进程;  
  75.             ResourceProcess();  
  76.         }  
  77.         pProcessMng[i].pid = iPid; //记录资源进程的进程号  
  78.         pProcessMng[i].iFlag = 0;   //把资源进程置为空闲  
  79.     }  
  80.       
  81.     iMaxProcessNum = iProcessNum;  
  82.   
  83.     //创建外部跟管理进程通信的消息队列;  
  84.     iMsgQue1 = CreateMsgQue();  
  85.   
  86.     //创建管理进程跟资源进程通信的消息队列;  
  87.     iMsgQue2 = CreateMsgQue();  
  88.   
  89.     //安装资源进程回收信号处理函数  
  90.     signal(SIGUSR1, ReleaseAProcess);     
  91.   
  92.     //开始接收外部传入的任务  
  93.     while(1)  
  94.     {  
  95.         //接收外部的工作请求  
  96.         iMsgLen = msgrcv(iMsgQue1, szBuffer, sizeof(szBuffer), 0);  
  97.           
  98.         //转发工作请求到资源进程处理消息队列  
  99.         iRtn = msgsnd(iMsgQue2, szBuffer, iMsgLen, 0);  
  100.       
  101.         //通知其中的一个空闲资源进程进行处理  
  102.         NoticeAIdleProcess();  
  103.     }  
  104. }  
  105.   
  106. //通知一个空闲资源进程进行处理  
  107. int NoticeAIdleProcess()  
  108. {  
  109.     int i;  
  110.       
  111.     for (i = 0; i < iMaxProcessNum; i++)  
  112.     {  
  113.         if (pProcessMng[i].iFlag == 0)  
  114.         {  
  115.             pProessMng[i].Flag = 1;  
  116.             kill(processMng[i].pid, SIGUSR1);  
  117.             return 0;  
  118.         }  
  119.     }  
  120.       
  121.     return -1;    
  122. }  
  123.   
  124. //回收一个处理完成的资源进程  
  125. void ReleaseAProcess(int iPid)  
  126. {  
  127.     int i;  
  128.       
  129.     for (i = 0; i < iMaxProcessNum; i++)  
  130.     {  
  131.         if (pProessMng[i].pid == iPid)  
  132.         {  
  133.             pProcessMng[i].iFlag = 0;  
  134.             return;  
  135.         }  
  136.     }  
  137.   
  138.     return;  
  139. }  
  140.   
  141. //资源进程的处理  
  142. void ResourceProcess()  
  143. {  
  144.     //安装有工作通知信号处理  
  145.     signal(SIGUSR1, SIG_IGN);  
  146.   
  147.     //设置只对SIGUSR1信号感兴趣  
  148.     sigprocmask()  
  149.     while(1)  
  150.     {  
  151.         //没有消息处理时挂起  
  152.         pause();  
  153.           
  154.         //处理工作  
  155.         void StartWork()  
  156.   
  157.         //通知管理进程工作处理完成  
  158.         NoticeMngProcessFinishedWork();   
  159.     }  
  160. }  
  161.   
  162. //处理消息  
  163. void StartWork()  
  164. {  
  165.     char szBuffer[64];  
  166.     int iMsgID;  
  167.     int iRtn;  
  168.       
  169.     iMsgID = msgget();  
  170.     iRtn = msgrcv(iMsgID, szBuffer, sizeof(szBuffer), 0);  
  171.       
  172.     //现在在子进程里取得了需要处理的消息,可以开始处理该消息直到消息处理完成  
  173.   
  174.     return;   
  175. }  
  176.   
  177. //通知管理进程回收资源进程  
  178. void NoticeMngProcessFinishedWork();  
  179. {  
  180.     kill(MngProcessPid, SIGUSR1);  
  181.       
  182.     return;  
  183. }  

 

如上,一个基本的进程池处理模型就建立好了, 当然你不能直接拿到编译,因为里面很多都是伪代码,另个上面的模型忽略了很多细节处理,很多地方是很不可靠的。

现在你是不是对进程池技术更了解了呢?


  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Python实现进程和线程的示例如下: 进程: from multiprocessing import Pool def f(x): return x*x if __name__ == '__main__': with Pool(5) as p: print(p.map(f, [1, 2, 3])) 线程: from multiprocessing.pool import ThreadPool def f(x): return x*x if __name__ == '__main__': with ThreadPool(5) as p: print(p.map(f, [1, 2, 3])) ### 回答2: Python中可以使用multiprocessing模块来实现进程和使用concurrent.futures模块来实现线程进程示例: ```python import multiprocessing def do_task(task): # 执行任务的函数 # ... if __name__ == '__main__': # 创建进程,设置最大进程数为4 pool = multiprocessing.Pool(processes=4) tasks = [task1, task2, task3, task4, task5] # 任务列表 # 向进程提交任务 for task in tasks: pool.apply_async(do_task, args=(task,)) # 关闭进程,表示不再接受新的任务 pool.close() # 阻塞等待所有任务完成 pool.join() ``` 线程示例: ```python import concurrent.futures def do_task(task): # 执行任务的函数 # ... if __name__ == '__main__': # 创建线程,设置最大线程数为4 pool = concurrent.futures.ThreadPoolExecutor(max_workers=4) tasks = [task1, task2, task3, task4, task5] # 任务列表 # 向线程提交任务 futures = [pool.submit(do_task, task) for task in tasks] # 等待所有任务完成并获取结果 for future in concurrent.futures.as_completed(futures): result = future.result() # 处理任务结果 # 关闭线程 pool.shutdown() ``` 以上是Python实现进程和线程的简单示例,实际使用时可以根据具体需求和任务类型进行适当的修改和优化。 ### 回答3: Python提供了multiprocessing模块来实现进程和线程。 1. 进程示例: ```python import multiprocessing def worker(num): """模拟一个工作任务""" print(f'Worker {num} is processing') if __name__ == '__main__': # 创建进程,最多同时运行3个进程 pool = multiprocessing.Pool(processes=3) # 向进程中添加任务 for i in range(5): pool.apply_async(worker, args=(i,)) # 关闭进程,不再接受新的任务 pool.close() # 等待所有任务完成 pool.join() ``` 上述示例中,我们使用`multiprocessing.Pool`创建了一个进程,可以同时运行3个进程。然后,使用`pool.apply_async`方法向进程中添加任务,每个任务由`worker`函数处理。最后,关闭进程并等待所有任务完成。 2. 线程示例: ```python import concurrent.futures def worker(num): """模拟一个工作任务""" print(f'Worker {num} is processing') if __name__ == '__main__': # 创建线程,最多同时运行3个线程 with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor: # 向线程中添加任务 for i in range(5): executor.submit(worker, i) ``` 上述示例中,我们使用`concurrent.futures.ThreadPoolExecutor`创建了一个线程,可以同时运行3个线程。然后,使用`executor.submit`方法向线程中添加任务,每个任务由`worker`函数处理。 以上就是Python中实现进程和线程的示例。通过使用进程和线程,我们可以并发地执行多个任务,提高程序的运行效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值