当前位置:文档之家› 进程间的同步和互斥-

进程间的同步和互斥-

实验报告1、实验名称进程间的互斥和同步2、小组成员:姓名+学号3、实验目的Linux命名信号量实现进程间的互斥和同步4、实验背景知识进程同步也是进程之间直接的制约关系,是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系。

进程间的直接制约关系来源于他们之间的合作。

比如说进程A需要从缓冲区读取进程B产生的信息,当缓冲区为空时,进程B因为读取不到信息而被阻塞。

而当进程A产生信息放入缓冲区时,进程B才会被唤醒。

进程互斥是进程之间的间接制约关系。

当一个进程进入临界区使用临界资源时,另一个进程必须等待。

只有当使用临界资源的进程退出临界区后,这个进程才会解除阻塞状态。

比如进程B需要访问打印机,但此时进程A占有了打印机,进程B会被阻塞,直到进程A释放了打印机资源,进程B才可以继续执行。

5、实验步骤演示大概步骤:先进行单次同步,把信号量先初始化为0,创建一个命名信号量,设置信号捕捉处理代码,安装捕捉信号;其次使用信号量进行同步和互斥的操作。

详细步骤:1.创建一个命名信号量,sem = sem_open(SEM_NAME, OPEN_FLAG, OPEN_MODE, INIT_V);2.创建子进程,pid = fork();3.V操作,sem_post(sem);4.P操作,sem_wait(sem);5.等待子进程结束,wait(&status);6.删掉在系统创建的信号量,sem_unlink(SEM_NAME);7.彻底销毁打开的信号量,sem_close(sem);8.信号捕捉处理,static void myhandler(void);9.迭代同步,两个信号量,开始时一个为1,一个为0,一个进程执行完换另一个执行;10.安装捕捉信号,signal(SIGINT,(void *)myhandler );11.创建一个命名信号量:sem1 = sem_open(SEM_NAME1, OPEN_FLAG, OPEN_MODE, 1);sem2 = sem_open(SEM_NAME2, OPEN_FLAG, OPEN_MODE, 0);12.创建子进程,pid = fork();13.if(0 == pid)P操作:sem_wait(sem1);V操作:sem_post(sem2);14.if(0 < pid)P操作:sem_wait(sem2);V操作:sem_post(sem1);15.static void mysem(char *str){int i = 0;//P操作sem_wait(sem);while('\0' != str[i]){printf("%c\n", str[i++]);sleep(1);}//V操作sem_post(sem);}进程排斥,在临界区设置PV操作16.创建一个命名信号量,sem = sem_open(SEM_NAME, OPEN_FLAG, OPEN_MODE, INIT_V);17.if(0 == pid){mysem("abcd");}18.if(0 < pid){mysem("1234");//等待子进程结束wait(&status);//删掉在系统创建的信号量sem_unlink(SEM_NAME);//彻底销毁打开的信号量sem_close(sem);}说明:命名信号量不带内存共享,编译时要带库文件-lpthread或-lrtint sem_wait(sem_t *sem); //P操作,若是信号量大于零则减一,否则阻塞在该函数位置等待.int sem_post(sem_t *sem); //V操作,信号量加一sem_t *sem_open(const char *name, int oflag);//打开信号量,flag参数与打开普通文件的标记一样sem_t *sem_open(const char *name, int oflag,mode_t mode, unsigned int value); //创建并打开信号量,value参数指的是信号量的初始值int sem_unlink(const char *name);//删除系统创建的信号量int sem_close(sem_t *sem);//关闭彻底销毁信号量6、实验源码#include <stdio.h>#include <errno.h>#include <semaphore.h>#include <fcntl.h>#define SEM_NAME "mysem"#define OPEN_FLAG O_RDWR|O_CREAT#define OPEN_MODE 00777#define INIT_V 0static sem_t *sem = NULL;static void mysem(char *str){int i = 0;while('\0' != str[i]){printf("%c\n", str[i++]);sleep(1);}}/*单次同步, 把信号量先初始化为0*/int main(void){pid_t pid = -1;int ret = -1;int status = -1;//创建一个命名信号量sem = sem_open(SEM_NAME, OPEN_FLAG, OPEN_MODE, INIT_V);//创建子进程pid = fork();if(-1 == (ret = pid)){perror("fork failed: ");goto _OUT;}if(0 == pid){mysem("abcd");//V操作sem_post(sem);}if(0 < pid){//P操作sem_wait(sem);mysem("1234");//等待子进程结束wait(&status);//删掉在系统创建的信号量sem_unlink(SEM_NAME);//彻底销毁打开的信号量sem_close(sem);}_OUT:return ret;}#include <stdio.h>#include <errno.h>#include <semaphore.h>#include <fcntl.h>#include <signal.h>#define SEM_NAME1 "mysem1"#define SEM_NAME2 "mysem2"#define OPEN_FLAG O_RDWR|O_CREAT#define OPEN_MODE 00777static sem_t *sem1 = NULL;static sem_t *sem2 = NULL;//临界区static void mysem(char *str){int i = 0;while('\0' != str[i]){printf("%c\n", str[i++]);sleep(1);}}//信号捕捉处理static void myhandler(void){//删掉在系统创建的信号量sem_unlink(SEM_NAME1);sem_unlink(SEM_NAME2);//彻底销毁打开的信号量sem_close(sem1);sem_close(sem2);}/*迭代同步,两个信号量,开始时一个为1,一个为0,一个进程执行完换另一个进程运行*/int main(void){pid_t pid = -1;int ret = -1;int status = -1;//安装捕捉信号signal(SIGINT,(void *)myhandler );//创建一个命名信号量sem1 = sem_open(SEM_NAME1, OPEN_FLAG, OPEN_MODE, 1);sem2 = sem_open(SEM_NAME2, OPEN_FLAG, OPEN_MODE, 0);//创建子进程pid = fork();if(-1 == (ret = pid)){perror("fork failed: ");goto _OUT;}if(0 == pid){while(1){//P操作sem_wait(sem1);mysem("abcd");//V操作sem_post(sem2);}}if(0 < pid){while(1){//P操作sem_wait(sem2);mysem("1234");//V操作sem_post(sem1);}//等待子进程结束wait(&status);}_OUT:return ret;}#include <stdio.h>#include <errno.h>#include <semaphore.h>#include <fcntl.h>#define SEM_NAME "mysem"#define OPEN_FLAG O_RDWR|O_CREAT#define OPEN_MODE 00777#define INIT_V 1static sem_t *sem = NULL;static void mysem(char *str){int i = 0;//P操作sem_wait(sem);while('\0' != str[i]){printf("%c\n", str[i++]);sleep(1);}//V操作sem_post(sem);}/*进程排斥,在临界区设置PV操作*/int main(void){pid_t pid = -1;int ret = -1;int status = -1;//创建一个命名信号量sem = sem_open(SEM_NAME, OPEN_FLAG, OPEN_MODE, INIT_V);//创建子进程pid = fork();if(-1 == (ret = pid)){perror("fork failed: ");goto _OUT;}if(0 == pid){mysem("abcd");}if(0 < pid){mysem("1234");//等待子进程结束wait(&status);//删掉在系统创建的信号量sem_unlink(SEM_NAME);//彻底销毁打开的信号量sem_close(sem);}_OUT:return ret;}。

相关主题