当前位置:文档之家› 计算机操作系统_进程间互斥与同步

计算机操作系统_进程间互斥与同步

进程间互斥与同步
实验内容:
编写算法,实现进程间对临界资源的互斥访问以及进程间的同步关系。

实验要求:
1、要求进程互斥使用文本文件;
2、假定文本文件txt1最大可写入30个字符;
3、写满后复制进程将文本文件的内容复制到另一个文本文件txt2中(无长度限制)。

4、复制进程复制完毕写入进程可再重新写入,重复执行3,4,直到给出停止命令。

5、实现进程间的同步和互斥。

代码:
#include<iostream>
#include<cstdio>//stdio.h
#include<cstdlib>//函数库
#include<unistd.h>//linux/unix的系统调用
#include<sys/sem.h>//信号量
#include<errno.h>
using namespace std;
typedef union _semnu{
int val;
struct semid_ds *buf;
ushort *array;
}semun;
//v操作
void v(int &sem_id)
{
struct sembuf sem_b;
sem_b.sem_num=0;
sem_b.sem_op=1;
sem_b.sem_flg=SEM_UNDO;
if(semop(sem_id,&sem_b,1)==-1)
{
cout<<"error"<<endl;
exit(0);
}
}
//p操作
void p(int &sem_id)
{
struct sembuf sem_b;
sem_b.sem_num=0;
sem_b.sem_op=-1;
sem_b.sem_flg=SEM_UNDO;
if(semop(sem_id,&sem_b,1)==-1)
{
cout<<"error"<<endl;
exit(0);
}
}
//设置信号量初值
void set(int sem_id,int val=1)
{
semun sem_un;
sem_un.val=val;
if(semctl(sem_id,0,SETVAL,sem_un)==-1)
{
if(errno==EEXIST)
cout<<"exist"<<endl;
cout<<"set"<<val<<"error"<<endl;
exit(0);
}
}
void del(int sem_id)
{
semun sem_un;
if(semctl(sem_id,0,IPC_RMID,sem_un)==-1)
cout<<"error"<<endl;
}
int main()
{
//互斥量
int sem_mutex=semget((key_t)8888,1,IPC_CREAT);
set(sem_mutexk,1);
int sem_full=semget((key_t)1234,1,IPC_CREAT);
cout<<sem_full<<endl;
//set semaphore full
set(sem_full,0);
int sem_empty=semget((key_t)1235,1,IPC_CREAT);
cout<<sem_empty<<endl;
//set semaphore emtpy
set(sem_empty,1);
FILE *fp1=fopen("./txt1","w");
FILE *fp2=fopen("./txt1","r");
FILE *fp3=fopen("./txt2","w");
pid_t id=fork();
if(id>0)//parent
{
//produce
//p(empty)
//
//v(full)
for(int i=0;i<5;i++)
{
p(sem_empty);
p(sem_mutex);//锁定临界区
cout<<"writing... "<<i<<endl;
fseek(fp1,0,SEEK_SET);
fputs("QWERTYUIOPASDFGHJKLZXCVBNM1234",fp1); fflush(fp1);
sleep(1);
cout<<"write done"<<endl;
v(sem_mutex);
v(sem_full);
}
fclose(fp1);
cout<<"txt2:"<<endl;
system("cat txt2 \n");
}else if(id==0)
{
//consume
//p(full)
//
//v(empty)
char buf[32];
buf[31]='\0';
fill(buf,buf+20,0);
for(int i=0;i<5;i++)
{
p(sem_full);
p(sem_mutex);//锁定临界区
cout<<"reading... "<<i<<endl;
fseek(fp2,0,SEEK_SET);
fgets(buf,30,fp2);
fputs(buf,fp3);
fflush(fp3); //由于缓冲方式的影响,30个字符不会立刻读取到buf 中,需要fflush
cout<<buf<<endl;
cout<<"read done"<<endl;
cout<<endl;
sleep(1);
v(sem_mutex);
v(sem_empty);
}
fclose(fp2);
fclose(fp3);
exit(0);
}else//error
{
cout<<"创建子进程失败!"<<endl;
exit(0);
}
// del(sem_full);
// del(sem_empty);
return0;
}
输出结果:
//注意要以root用户运行程序
196608
229377
writing 0
write done
reading 0
QWERTYUIOPASDFGHJKLZXCVBNM123
read done
writing (1)
write done
reading (1)
QWERTYUIOPASDFGHJKLZXCVBNM123 read done
writing (2)
write done
reading (2)
QWERTYUIOPASDFGHJKLZXCVBNM123 read done
writing (3)
write done
reading (3)
QWERTYUIOPASDFGHJKLZXCVBNM123 read done
writing (4)
write done
txt2:
reading (4)
QWERTYUIOPASDFGHJKLZXCVBNM123 read done。

相关主题