版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、江西理工大学应用科学学院嵌入式系统开发技术课程设计专 业: 电子信息工程 班 级: 083 学 号: 21号 25号 姓 名: 熊冰宇 陈志伟 设计题目: 多进程程序设计 2011年11月课程设计评分表姓 名班 级学 号课设题目指导教师评分项目满分分值得分设计文档(30分)文档格式封面2页面布局4目录格式3图表质量2页眉页脚2文档内容内容完整性6内容逻辑性5内容正确性6程序代码(30分)程序功能15编程规范7编程文档8答辩(20分)课题陈述7问题答辩10是否超时3考勤(20分)20总评成绩指导教师评语签名: 年 月 日教研室意见签名: 年 月 日目录1 设计概述11.1 设计简介11.2设计目
2、的11.3设计要求12 设计内容22.1编写目的22.2需求概述22.3设计概述93编写代码144实验分析报告154.1实验结果15实验总结176附录211 设计概述1.1 设计简介嵌入式系统软件的实时性是其非常重要的特性,采用多进程设计可以提高系统的效率,增强系统的实时性,因此,掌握多进程编程,是学习嵌入式Linux必须达到的目标1.2 设计目的本课程设计通过设计多进程程序,掌握创建多进程的方法,掌握通过有名管道实现进程之间的通信,掌握进程中运行现有程序的方法。“生产者消费者”问题是一个著名的同时性编程问题的集合。通过学习经典的“生产者消费者”问题的实验,读者可以进一步熟悉Linux中的多线
3、程编程,并且掌握用信号量处理处理线程间的同步和互斥问题。1.3 设计要求本课题所设计的系统要求实现以下功能。l 创建子进程1及子进程2。l 子进程1创建子进程A、B,子进程1等待子进程A、B退出后退出。l 子进程A、B之间通过有名管道FIFO1进行通信,实现生产者-消费者功能。l 子进程2创建子进程C、D,子进程C运行“ls l”命令,子进程D通过有名管道FIFO1作为消费者与进程A通信。2设计内容2.1编写目的通过编写多进程程序,使读者熟练掌握fork()、exec()、wait()和waitpid()等函数的实用,进一步理解在Linux中多进程编程的步骤。2.2需求概述l 创建子进程1及子
4、进程2。l 子进程1创建子进程A、B,子进程1等待子进程A、B退出后退出。l 子进程A、B之间通过有名管道FIFO1进行通信,实现生产者-消费者功能。l 子进程2创建子进程C、D,子进程C运行“ls l”命令,子进程D通过有名管道FIFO1作为消费者与进程A通信。2.3设计概述(1)画出设计的流程图 该设计的流程图如图2.3所示 图2.3多路进程流程图3编写代码/* multi_proc.c */#include #include #include #include #include int main(void)pid_t child1, child2, child;/*创建两个子进程*/ch
5、ild1 = fork();/*子进程1的出错处理*/if (child1 = -1)printf(Child1 fork errorn);exit(1);else if (child1 = 0) /*在子进程1中调用execlp函数*/printf(In child1: execute ls -ln);if (execlp(ls, ls, -l, NULL) 0)printf(Child1 execlp errorn); else /*在父进程中等待子进程2的退出*/ child2 = fork(); if (child2 = -1) /*子进程2的出错处理*/ printf(Child2
6、fork errorn); exit(1); else if( child2 = 0 ) /*在子进程2中使其暂停5s*/ printf(In child2: sleep for 5 seconds and then exitn); sleep(5); exit(0); printf(In father process:n); child = waitpid(child1, NULL, 0); if (child = child1) printf(Get child1 exit coden); else printf(Error occured!n); do child = waitpid(c
7、hild2, NULL, WNOHANG ); if (child = 0) printf(The child2 process has not exited!n); sleep(1); while (child = 0); if (child = child2) printf(Get child2 exit coden); else printf(Error occured!n); exit(0);/*producer-customer.c*/#include #include #include #include #include #include #include #include #de
8、fine MYFIFOmyfifo#define BUFFER_SIZE3 /* 缓冲区的单元数 */#define UNIT_SIZE5 /* 每个单元的大小 */#define RUN_TIME30 /* 运行时间 */#define DELAY_TIME_LEVELS5.0/* 周期的最大值 */void *producer(void *arg);void *customer(void *arg);int fd;time_t end_time;sem_t mutex,full,avail;void *producer(void *arg)int real_write;int delay_
9、time = 0;while(time(NULL) end_time)delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX) / 2.0) + 1;sleep(delay_time);/*P操作信号量avail和mutex*/sem_wait(&avail);sem_wait(&mutex);printf(nProducer: delay = %dn, delay_time);/*生产者写入数据*/if (real_write = write(fd, hello, UNIT_SIZE) = -1)if(errno = EAGAIN)pr
10、intf(The FIFO has not been read yet.Please try latern);elseprintf(Write %d to the FIFOn, real_write);/*V操作信号量full和mutex*/sem_post(&full);sem_post(&mutex);pthread_exit(NULL);void *customer(void *arg)unsigned char read_bufferUNIT_SIZE;int real_read;int delay_time;while(time(NULL) end_time)delay_time =
11、 (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX) + 1; sleep(delay_time); /*P操作信号量full和mutex*/ sem_wait(&full); sem_wait(&mutex); memset(read_buffer, 0, UNIT_SIZE); printf(nCustomer: delay = %dn, delay_time); if (real_read = read(fd, read_buffer, UNIT_SIZE) = -1)if (errno = EAGAIN)printf(No data yetn);pr
12、intf(Read %s from FIFOn, read_buffer);/*V操作信号量avail和mutex*/sem_post(&avail);sem_post(&mutex);pthread_exit(NULL);int main()pthread_t thrd_prd_id,thrd_cst_id;pthread_t mon_th_id;int ret;srand(time(NULL);end_time = time(NULL) + RUN_TIME;/*创建有名管道*/if(mkfifo(MYFIFO, O_CREAT|O_EXCL) 0) & (errno != EEXIST)
13、printf(Cannot create fifon);return errno;/*打开管道*/fd = open(MYFIFO, O_RDWR);if (fd = -1)printf(Open fifo errorn);return fd;/*初始化互斥信号量为1*/ret = sem_init(&mutex, 0, 1);/*初始化avail信号量为N*/ret += sem_init(&avail, 0, BUFFER_SIZE);/*初始化full信号量为0*/ret += sem_init(&full, 0, 0);if (ret != 0)printf(Any semaphore
14、 initialization failedn);return ret;/*创建两个线程*/ret = pthread_create(&thrd_prd_id, NULL, producer, NULL);if (ret != 0)printf(Create producer thread errorn);return ret;ret = pthread_create(&thrd_cst_id, NULL, customer, NULL);if(ret != 0)printf(Create customer thread errorn);return ret;pthread_join(thrd
15、_prd_id, NULL);pthread_join(thrd_cst_id, NULL);close(fd);unlink(MYFIFO);return 0;4实验分析报告4.1实验结果5实验总结1. 写出Linux系统中线程同步实现机制有哪些?怎样使用?Linux系统中线程同步实现机制通过对互斥变量Mutex、信号灯Semophore、条件变量Conditions的设置实现线程的同步。(1) 互斥变量(Mutex)互斥变量的类型为pthread_mutex_t。可以声明多个互斥量。在声明该变量后,你需要调用pthread_mutex_init()来创建该变量。pthread_mutex_
16、init的格式如下: int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex-attr_t *mutexattr); 第一个参数mutext,也就是你之前声明的那个互斥量,第二个参数为该互斥量的属性。在创建该互斥量之后,你便可以使用它了。要得到互斥量,你需要调用下面的函数: int pthread_mutex_lock(pthread_mutex_t *mutex);该函数用来给互斥量上锁,也就是等待操作。互斥量一旦被上锁后,其他线程如果想给该互斥量上锁,那么就会阻塞在这个操作上。如果在此之前该互斥量已经被其他线程上
17、锁,那么该操作将会一直阻塞在这个地方,直到获得该锁为止。在得到互斥量后,就可以进入关键代码区了。同样,在操作完成后,你必须调用int pthread_mutex_unlock(pthread_mutex_t *mutex);函数来给互斥量解锁,也就是释放。这样其他等待该锁的线程才有机会获得该锁,否则其他线程将会永远阻塞。(2)信号灯机制(Semaphore)信号灯其实就是一个计数器,也是一个整数。每一次调用wait操作将会使semaphore值减一,而如果semaphore值已经为0,则wait操作将会阻塞。每一次调用post操作将会使semaphore值加一。生产者线程在每次往缓冲池中添加产
18、品后调用post操作,信号灯值会加一。这样阻塞的工作线程就会停止阻塞,继续往下执行。信号灯的类型为sem_t。在声明后必须调用sem_init()。需要传递两个参数,第一个参数就是你之前声明的sem_t变量,第二个必须为0。当你不再需要信号灯时,你必须调用sem_destroy()来释放资源。等待信号灯的操作为sem_wait()。和互斥量一样,等待信号灯也有一个非阻塞的操作,sem_trywait()。该操作在没有信号灯的时候返回EAGAIN。(3)条件变量(Conditions)如果现在在等待一个信号。如果该信号被设置,则继续运行。如果没有条件变量,它将会不停的去查询该信号是否被设置,这样
19、就会浪费大量的处理机。而通过使用条件变量,我们就可以将等待信号的线程阻塞,直到有信号的时候再去唤醒它。条件变量的类型是pthread_cond_t。a.声明pthread_cond_t变量后,调用pthread_cond_init()函数,第一个参数为之前声明的变量。第二个参数在Linux中不起作用。b.声明一个pthread_mutex_t变量,并调用pthread_mutex_init()初始化。c.调用pthread_cond_signal()发出信号。如果此时有线程在等待该信号,那么该线程将会唤醒。如果没有,该信号就会别忽略。d.如果想唤醒所有等待该信号的线程,调用pthread_co
20、nd_broadcast()。e.调用pthread_cond_wait()等待信号。如果没有信号,线程将会阻塞,直到有信号。该函数的第一个参数是条件变量,第二个参数是一个mutex。在调用该函数之前必须先获得互斥量。如果线程阻塞,互斥量将立刻会被释放。2. 实验中遇到了哪些问题,是怎样解决的?在实验过程中还遇到了一些问题,在函数编译时,我输入命令gcc o shiyan2 shiyan2.c时系统m没有执行,后来请教同学后将命令改为:gcc shiyan2.c -lpthread后运行成功。附录生产者消费者实验代码#include #include #include sem_t blank_
21、number, product_number;pthread_cond_t full = PTHREAD_COND_INITIALIZER;pthread_cond_t empty = PTHREAD_COND_INITIALIZER;pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;#define NUM 15 struct P_Queue char productcNUM; int front, rear; int num; ;void *producer1(void *arg) struct P_Queue *q; q = (struct
22、P_Queue *) arg; while (1) pthread_mutex_lock(&lock); while (q-num = NUM) pthread_cond_wait(&full, &lock); sem_wait(&blank_number); char c = rand() % 26 + a; q-rear = (q-rear + 1) % NUM; q-productcq-rear = c; printf(缓冲池1的产品是:%cn, q-productcq-rear); q-num+; printf(产品数量:%dn, q-num); sem_post(&product_n
23、umber); if (q-num = 1) pthread_cond_signal(&empty); pthread_mutex_unlock(&lock); sleep(rand() % 2); void *producer2(void *arg) struct P_Queue *q; q = (struct P_Queue *) arg; while (1) pthread_mutex_lock(&lock); while (q-num = NUM) pthread_cond_wait(&full, &lock); sem_wait(&blank_number); char c = ra
24、nd() % 26 + A; q-rear = (q-rear + 1) % NUM; q-productcq-rear = c; printf(缓冲池2的产品是:%cn, q-productcq-rear); q-num+; printf(产品数量:%dn, q-num); sem_post(&product_number); if (q-num = 1) pthread_cond_signal(&empty); pthread_mutex_unlock(&lock); sleep(rand() % 2); void *consumer1(void *arg) struct P_Queue
25、*q; q = (struct P_Queue *) arg; while (1) pthread_mutex_lock(&lock); while (q-num = 0) pthread_cond_wait(&empty, &lock); sem_wait(&product_number); q-front = (q-front + 1) % NUM; char c = q-productcq-front; q-productcq-front = ; q-num-; printf(消费者1显示内容: %cn, c); printf(产品数量:%dn, q-num); sem_post(&bl
26、ank_number); if (q-num = NUM - 1) pthread_cond_signal(&full); pthread_mutex_unlock(&lock); sleep(rand() % 2); void *consumer2(void *arg) struct P_Queue *q; q = (struct P_Queue *) arg; while (1) pthread_mutex_lock(&lock); while (q-num = 0) pthread_cond_wait(&empty, &lock); sem_wait(&product_number); q-front = (q-front + 1) % NUM;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年黑龙江旅游职业技术学院单招综合素质考试模拟试题带答案解析
- 2026年贵州装备制造职业学院高职单招职业适应性测试备考试题有答案解析
- 2026年河南工业和信息化职业学院单招综合素质考试模拟试题带答案解析
- 2026年长沙南方职业学院单招综合素质笔试备考题库附答案详解
- 2026年安徽国际商务职业学院高职单招职业适应性考试模拟试题带答案解析
- 2026年福州科技职业技术学院单招职业技能考试参考题库带答案解析
- 投资合作协议合同协议(2025年)
- 2026年鹤壁职业技术学院单招综合素质笔试模拟试题带答案解析
- 2026年河南工业和信息化职业学院单招综合素质笔试模拟试题带答案解析
- 2026年河南经贸职业学院高职单招职业适应性测试备考试题有答案解析
- 2025年学校食堂从业人员食品安全知识培训考试试题(附答案)
- 2025年建筑信息化行业分析报告及未来五至十年行业发展报告
- 建筑防欠薪管理制度
- 中国共产主义青年团纪律处分条例试行解读学习
- 2025年广东省深圳市中考英语复习听说题型课件信息复述提问
- 咖啡消费人群的细分与定位-全面剖析
- 09.品质月报统计表模板
- 2024-2025学年北京朝阳区九年级初三(上)期末历史试卷(含答案)
- DB11T 354-2023 生活垃圾收集运输管理规范
- 赤石特大桥施工安全风险评估报告
- QBT 2770-2006 羽毛球拍行业标准
评论
0/150
提交评论