2013年(12)
分类: 嵌入式
2013-07-30 23:51:14
系统编程的一个项目——用线程池来实现并行文件的拷贝。这个项目总共要求写了三个版本:(1)用链表和线程池来实现文件的并行拷贝;(2) 用有限缓冲区和线程池来实现; (3) 用进程扇来实现。具体分析如下:
在写线程池的时候,根据要求写完,主要的问题:
(1) 线程池的初始化中,要创建线程,创建多少个线程都用户自己定义,通过命令行参数得到线程的个数。
(2)回调函数的使用,传参要注意,pthread_create(pool->threadid + i,NULL,thread_routine,NULL)),注意每个参数的含义及用法。在thread_routine(函数执行体)去具体实现某一个得到的函数(这个函数是从一个CThread_worker 结构体类型中的回调函数),这里是把定义的CThread_worker *worker从一个链表中拿下来,然后去执行回调函数,”worker->process();”这样就执行了
(3)说一下回调函数的来龙去脉:首先定义好一个CThread_worker链表,写一个void add_worker(*(*process)(* arg),*arg)的函数来向链表中添加东西(CThread_worker类型的结构体)。Main函数调用这个add_worker函数把具体的函数的指针传进去,这样就实现了。当thread_routine函数有一个线程被唤醒时执行回调函数,具体实现看代码。
(4) 还有就是具体的函数了:这里拿void *copyfile(void *arg)作例子,看void *copyfile(void *arg)函数要实现的功能以及它需要的参数,然后怎么样才能把这些参数弄出来,这里就是要生产者product_creat函数要做的事了,要拷贝文件就要两个文件的fd(文件描述符),两个fd要封装成一个参数传过去,就要用结构体。完了之后把worker挂到链表上去。这就是生产者要干的事情。
这个版本实现的挺快的,往往越快实现的越感觉没学到什么东西,所以这个版本也没怎么发现多少要注意的东西。主要看实现的代码。
最重要的是线程的同步问题,这方面要理清楚,锁、还有条件变量,这里用了两个条件变量来控制线程的同步。Getitem() 和putitem() 。
进程之间通信,目前学过的有,pipe(管道,父子之间才能用)、fifo(命名管道,进程间都可用)、共享内存、消息队列等。在本例中使用的是最简单的方法——pipe来实现父子间的通信,创建子进程来做copyfile工作,把返回的bytesread通过管道传给父进程。特别要强调的是父子之间的变量的使用,千万要头脑清晰,本人就犯了个错,把子进程中被赋值的变量自以为父进程也能用,结果这个bug查了半天,引以为戒啊!!