文档详情

信号量的实现和应用.doc

发布:2017-05-22约4.89千字共7页下载文档
文本预览下载声明
信号量的实现和应用 难度系数:☆ 实验目的 加深对进程同步与互斥概念的认识; 掌握信号量的使用,并应用它解决生产者——消费者问题; 掌握信号量的实现原理。 实验内容 本次实验的基本内容是: 在Ubuntu下编写程序,用信号量解决生产者——消费者问题; 在0.11中实现信号量,用生产者—消费者程序检验之。 用信号量解决生产者—消费者问题 在Ubuntu上编写应用程序“pc.c”,解决经典的生产者—消费者问题,完成下面的功能: 建立一个生产者进程,N个消费者进程(N1); 用文件建立一个共享缓冲区; 生产者进程依次向缓冲区写入整数0,1,2,...,M,M=500; 消费者进程从缓冲区读数,每次读一个,并将读出的数字从缓冲区删除,然后将本进程ID和数字输出到标准输出; 缓冲区同时最多只能保存10个数。 一种可能的输出效果是: 10: 0 10: 1 10: 2 10: 3 10: 4 11: 5 11: 6 12: 7 10: 8 12: 9 12: 10 12: 11 12: 12 …… 11: 498 11: 499 其中ID的顺序会有较大变化,但冒号后的数字一定是从0开始递增加一的。 pc.c中将会用到sem_open()、sem_close()、sem_wait()和sem_post()等信号量相关的系统调用,请查阅相关文档。 《UNIX环境高级编程》是一本关于Unix/Linux系统级编程的相当经典的教程。校园网用户可以在/study/Computer_Science/Linux_Unix/?下载,后续实验也用得到。如果你对POSIX编程感兴趣,建议买一本常备手边。 实现信号量 Linux在0.11版还没有实现信号量,Linus把这件富有挑战的工作留给了你。如果能实现一套山寨版的完全符合POSIX规范的信号量,无疑是很有成就感的。但时间暂时不允许我们这么做,所以先弄一套缩水版的类POSIX信号量,它的函数原型和标准并不完全相同,而且只包含如下系统调用: /man/7/sem_overviewusg=AFQjCNGsL7S0Ey7Ri6QFze-4ss4oBWTQxg符合POSIX规范的信号量,无疑是很有成就感的。但时间暂时不允许我们这么做,所以先弄一套缩水版的类POSIX信号量,它的函数原型和标准并不完全相同,而且只包含如下系统调用: sem_t *sem_open(const char *name, unsigned int value); int sem_wait(sem_t *sem); int sem_post(sem_t *sem); int sem_unlink(const char *name); sem_t是信号量类型,根据实现的需要自定义。 sem_open()的功能是创建一个信号量,或打开一个已经存在的信号量。 name是信号量的名字。不同的进程可以通过提供同样的name而共享同一个信号量。如果该信号量不存在,就创建新的名为name的信号量;如果存在,就打开已经存在的名为name的信号量。 value是信号量的初值,仅当新建信号量时,此参数才有效,其余情况下它被忽略。 当成功时,返回值是该信号量的唯一标识(比如,在内核的地址、ID等),由另两个系统调用使用。如失败,返回值是NULL。 sem_wait()就是信号量的P原子操作。如果继续运行的条件不满足,则令调用进程等待在信号量sem上。返回0表示成功,返回-1表示失败。 sem_post()就是信号量的V原子操作。如果有等待sem的进程,它会唤醒其中的一个。返回0表示成功,返回-1表示失败。 sem_unlink()的功能是删除名为name的信号量。返回0表示成功,返回-1表示失败。 在kernel目录下新建“sem.c”文件实现如上功能。然后将pc.c从Ubuntu移植到0.11下,测试自己实现的信号量。 实验报告 完成实验后,在实验报告中回答如下问题: 在pc.c中去掉所有与信号量有关的代码,再运行程序,执行效果有变化吗?为什么会这样? 实验的设计者在第一次编写生产者——消费者程序的时候,是这么做的: Producer() { P(Mutex); //互斥信号量 生产一个产品item; P(Empty); //空闲缓存资源 将item放到空闲缓存中; V(Full); //产品资源 V(Mutex); } Consumer() { P(Mutex); P(Full); 从缓存区取出一个赋值给item; V(Empty); 消费产品item; V(Mutex); } 这样可行吗?如果可行,那么它和标准解法在执行效果上会有什么不同?如果不
显示全部
相似文档