进程同步(linux环境)
生产者消费者问题
生产者
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<semaphore.h>
#include<fcntl.h>
#include<sys/stat.h>
int main() {
int i=0,n;
sem_t *mutex=sem_open("mutex",O_CREAT,0666,1);
sem_t *empty=sem_open("empty",O_CREAT,0666,5);
sem_t *full=sem_open("full",O_CREAT,0666,0);
for(i=0; i<20; i++) {
sem_wait(empty);
sem_wait(mutex);
sem_getvalue(full,&n);
printf("Producerr put a production! Production Num:%d\n",n+1);
sem_post(mutex);
sem_post(full);
sleep(rand()%3);
}
sem_close(mutex);
sem_close(empty);
sem_close(full);
sem_unlink("mutex");
sem_unlink("empty");
sem_unlink("full");
return 0;
}
消费者
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<semaphore.h>
#include<fcntl.h>
#include<sys/stat.h>
int main() {
int i=0,n;
sem_t *mutex=sem_open("mutex",O_CREAT,0666,1);
sem_t *empty=sem_open("empty",O_CREAT,0666,5);
sem_t *full=sem_open("full",O_CREAT,0666,0);
for(i=0; i<20; i++) {
sem_wait(full);
sem_wait(mutex);
sem_getvalue(full,&n);
printf("Consumer get a production! Production Num:%d\n",n);
sem_post(mutex);
sem_post(empty);
sleep(rand()%3);
}
sem_close(mutex);
sem_close(empty);
sem_close(full);
sem_unlink("mutex");
sem_unlink("empty");
sem_unlink("full");
return 0;
}
哲学家进餐问题
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<semaphore.h>
#include<fcntl.h>
#include<sys/stat.h>
int main(int argc,char *argv[]) {
int name;
int i=0;
if(argc>1) {
name=argv[1][0];
name-=48;
}
sem_t *room=sem_open("mysem",O_CREAT,0666,4);
sem_t *chopstick[5];
for(i=0;i<5;i++){
chopstick[i]=sem_open("chopstick"+i,O_CREAT,0666,1);
}
for(i=0;i<5;i++){
sleep(rand()%3);
sem_wait(room);
sem_wait(chopstick[name-1]);
sem_wait(chopstick[name%5]);
printf("philosopher %d eating\n",name);
sem_post(chopstick[name-1]);
sem_post(chopstick[name%5]);
sem_post(room);
}
printf("philosopher %d full up\n",name);
sem_close(room);
for(i=0;i<5;i++){
sem_close(chopstick[i]);
}
sem_unlink("room");
for(i=0;i<5;i++){
sem_unlink("chopstick"+i);
}
}
/*
./philosopher 1 & ./philosopher 2 & ./philosopher 3 & ./philosopher 4 & ./philosopher 5
*/
小和尚打水老和尚喝水问题
小和尚
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<semaphore.h>
#include<fcntl.h>
#include<sys/stat.h>
int main(int argc,char *argv[]) {
char* name;
int i=0,n;
if(argc>1) {
name=argv[1];
}
sem_t *mutexWell=sem_open("mutexWell",O_CREAT,0666,1);
sem_t *mutexBucket=sem_open("mutexBucket",O_CREAT,0666,3);
sem_t *mutexVat=sem_open("mutexVat",O_CREAT,0666,1);
sem_t *emptyVat=sem_open("emptyVat",O_CREAT,0666,10);
sem_t *fullVat=sem_open("fullVat",O_CREAT,0666,0);
for(i=0; i<5; i++) {
sleep(rand()%2);
sem_wait(emptyVat);
sem_wait(mutexBucket);
printf("little monk %s get a bucket.\n",name);
sleep(rand()%2);
sem_wait(mutexWell);
printf("little monk %s get the water from well.\n",name);
sem_post(mutexWell);
sleep(rand()%2);
sem_wait(mutexVat);
sem_getvalue(fullVat,&n);
printf("little monk %s put the into vat. Vat: %d\n",name,n+1);
sem_post(mutexVat);
sem_post(fullVat);
sem_post(mutexBucket);
}
sem_close(mutexWell);
sem_close(mutexBucket);
sem_close(mutexVat);
sem_close(emptyVat);
sem_close(fullVat);
sem_unlink("mutexWell");
sem_unlink("mutexVat");
sem_unlink("mutexBucket");
sem_unlink("emptyVat");
sem_unlink("fullVat");
return 0;
}
/*
./lm2 1 & ./lm2 2 & ./lm2 3 & ./bm 1 & ./bm 2
*/
老和尚
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<semaphore.h>
#include<fcntl.h>
#include<sys/stat.h>
int main(int argc,char *argv[]) {
char* name;
int i=0,n;
if(argc>1) {
name=argv[1];
}
sem_t *mutexWell=sem_open("mutexWell",O_CREAT,0666,1);
sem_t *mutexBucket=sem_open("mutexBucket",O_CREAT,0666,3);
sem_t *mutexVat=sem_open("mutexVat",O_CREAT,0666,1);
sem_t *emptyVat=sem_open("emptyVat",O_CREAT,0666,10);
sem_t *fullVat=sem_open("fullVat",O_CREAT,0666,0);
for(i=0; i<5; i++) {
sleep(rand()%2);
sem_wait(fullVat);
sem_wait(mutexBucket);
printf("big monk %s get a bucket.\n",name);
sleep(rand()%2);
sem_wait(mutexVat);
sem_getvalue(fullVat,&n);
printf("big monk %s drink the water.Vat: %d \n ",name,n);
sem_post(mutexVat);
sem_post(emptyVat);
sem_post(mutexBucket);
}
sem_close(mutexWell);
sem_close(mutexBucket);
sem_close(mutexVat);
sem_close(emptyVat);
sem_close(fullVat);
sem_unlink("mutexWell");
sem_unlink("mutexVat");
sem_unlink("mutexBucket");
sem_unlink("emptyVat");
sem_unlink("fullVat");
return 0;
}
作业调度算法模拟
- 先来先服务(FCFS)算法、短作业优先(SJF)算法、高响应比优先(HRRF)算法、高优先权优先(HPF)算法
- 输入格式,以文件形式输入作业信息
- 结果示例
源码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include<iostream>
#include <algorithm>
using namespace std;
//无穷
const int INF=1e6;
//最大作业数量
const int MAXJOB=50;
//作业的数据结构
typedef struct node {
int number;//作业号
int reach_time;//作业抵达时间
int need_time;//作业的执行时间
int privilege;//作业优先权
float excellent;//响应比
int start_time;//作业开始时间
int wait_time;//等待时间
int visited;//作业是否被访问过
bool isreached;//作业是否抵达
} job;
job jobs[MAXJOB];//作业序列
int quantity;//作业数量
int cmp(job a, job b) {
return a.reach_time<b.reach_time;
}
//初始化作业序列
void initial_jobs() {
int i;
for(i=0; i<MAXJOB; i++) {
jobs[i].number=0;
jobs[i].reach_time=0;
jobs[i].privilege=0;
jobs[i].excellent=0;
jobs[i].start_time=0;
jobs[i].wait_time=0;
jobs[i].visited=0;
jobs[i].isreached=false;
}
quantity=0;
}
//重置全部作业信息
void reset_jinfo() {
int i;
for(i=0; i<MAXJOB; i++) {
jobs[i].start_time=0;
jobs[i].wait_time=0;
jobs[i].visited=0;
jobs[i].isreached=false;
}
}
//检查到达的作业
void checkReached(int current_time) {
int i;
for(i=0; i<quantity; i++) {
if(!jobs[i].isreached&&jobs[i].reach_time<=current_time) {
jobs[i].isreached=true;
}
}
}
//查找当前current_time已到达未执行的最短作业,若无返回-1
int findminjob(job jobs[],int count) {
int minjob=-1;//=jobs[0].need_time;
int minloc=-1;
for(int i=0; i<count; i++) {
if(minloc==-1) {
if(jobs[i].isreached && jobs[i].visited==0) {
minjob=jobs[i].need_time;
minloc=i;
}
} else if(minjob>jobs[i].need_time&&jobs[i].visited==0&&jobs[i].isreached) {
minjob=jobs[i].need_time;
minloc=i;
}
}
return minloc;
}
//查找最早到达作业,若全部到达返回-1.
int findrearlyjob(job jobs[],int count) {
int rearlyloc=-1;
int rearlyjob=-1;
for(int i=0; i<count; i++) {
if(!jobs[i].visited) {
rearlyloc=i;
break;
}
// if(rearlyloc==-1) {
// if(jobs[i].visited==0) {
// rearlyloc=i;
// rearlyjob=jobs[i].reach_time;
// }
// } else if(rearlyjob>jobs[i].reach_time&&jobs[i].visited==0) {
// rearlyjob=jobs[i].reach_time;
// rearlyloc=i;
// }
}
return rearlyloc;
}
//查找响应比最大的作业
int findHRRjob(job jobs[],int count) {
int loc=-1;
int hrr=-1;
for(int i=0; i<count; i++) {
if(loc==-1) {
if(jobs[i].isreached&&!jobs[i].visited) {
hrr=jobs[i].excellent;
loc=i;
}
} else if(hrr<jobs[i].excellent&&jobs[i].isreached&&!jobs[i].visited) {
hrr=jobs[i].excellent;
loc=i;
}
}
return loc;
}
//查找优先权最高的作业
int findHighPrivilegeJob(){
int loc=-1;
int p=-1;
for(int i=0;i<quantity;i++){
if(jobs[i].isreached&&!jobs[i].visited&&p<jobs[i].privilege){
loc=i;
p=jobs[i].privilege;
}
}
return loc;
}
//更新响应比
void refreshHRR(int current_time) {
int i;
for(i=0; i<quantity; i++) {
if(jobs[i].isreached&&!jobs[i].visited) {
jobs[i].excellent=1+(current_time-jobs[i].reach_time)*1.0/jobs[i].need_time;
}
}
}
//读取作业数据
void readJobdata() {
FILE *fp;
char fname[20];
int i;
//输入测试文件文件名
printf("please input job data file name\n");
scanf("%s",fname);
if((fp=fopen(fname,"r"))==NULL) {
printf("error, open file failed, please check filename:\n");
} else {
//依次读取作业信息
while(!feof(fp)) {
if(fscanf(fp,"%d %d %d %d",&jobs[quantity].number,&jobs[quantity].reach_time,&jobs[quantity].need_time,&jobs[quantity].privilege)==4)
quantity++;
}
//打印作业信息
printf("output the origin job data\n");
printf("---------------------------------------------------------------------\n");
printf("\tjobID\treachtime\tneedtime\tprivilege\n");
for(i=0; i<quantity; i++) {
printf("\t%-8d\t%-8d\t%-8d\t%-8d\n",jobs[i].number,jobs[i].reach_time,jobs[i].need_time,jobs[i].privilege);
}
}
sort(jobs,jobs+quantity,cmp);
}
//FCFS
void FCFS() {
int i;
int current_time=0;
int loc;
int total_waitime=0;
int total_roundtime=0;
//输出作业流
printf("\n\nFCFS算法作业流\n");
printf("------------------------------------------------------------------------\n");
printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");
//每次循环找出最先到达的作业并打印相关信息
for(i=0; i<quantity; i++) {
loc=findrearlyjob(jobs,quantity);
if(jobs[loc].reach_time>current_time) {
jobs[loc].start_time=jobs[loc].reach_time;
current_time=jobs[loc].reach_time;
} else {
jobs[loc].start_time=current_time;
}
jobs[loc].wait_time=current_time-jobs[loc].reach_time;
printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n",jobs[loc].number,jobs[loc].reach_time,jobs[loc].start_time,jobs[loc].wait_time,
jobs[loc].wait_time+jobs[loc].need_time);
jobs[loc].visited=1;
current_time+=jobs[loc].need_time;
total_waitime+=jobs[loc].wait_time;
total_roundtime=total_roundtime+jobs[loc].wait_time+jobs[loc].need_time;
}
printf("总等待时间:%-8d 总周转时间:%-8d\n",total_waitime,total_roundtime);
printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n",(float)total_waitime/(quantity),(float)total_roundtime/(quantity));
}
//短作业优先作业调度
void SFJschdulejob(job jobs[],int count) {
int i,j;
int current_time=0;
int loc;
int total_waitime=0;
int total_roundtime=0;
//输出作业流
printf("\n\nSJF算法作业流\n");
printf("------------------------------------------------------------------------\n");
printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");
//查找最先到达的作业
current_time=INF;
for(i=0; i<quantity; i++) {
if(current_time>jobs[i].reach_time) {
current_time=jobs[i].reach_time;
}
}
//每次循环找出执行时间最短的作业并打印相关信息
for(i=0; i<quantity; i++) {
checkReached(current_time);
loc=findminjob(jobs,quantity);
while(loc==-1) {
current_time=INF;
for(j=0; j<quantity; j++) {
if(!jobs[j].isreached&¤t_time>jobs[j].reach_time) {
current_time=jobs[j].reach_time;
}
}
checkReached(current_time);
loc=findminjob(jobs,quantity);
}
if(jobs[loc].reach_time>current_time) {
jobs[loc].start_time=jobs[loc].reach_time;
current_time=jobs[loc].reach_time;
} else {
jobs[loc].start_time=current_time;
}
jobs[loc].wait_time=current_time-jobs[loc].reach_time;
printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n",jobs[loc].number,jobs[loc].reach_time,jobs[loc].start_time,jobs[loc].wait_time,
jobs[loc].wait_time+jobs[loc].need_time);
jobs[loc].visited=1;
current_time+=jobs[loc].need_time;
total_waitime+=jobs[loc].wait_time;
total_roundtime=total_roundtime+jobs[loc].wait_time+jobs[loc].need_time;
}
printf("总等待时间:%-8d 总周转时间:%-8d\n",total_waitime,total_roundtime);
printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n",(float)total_waitime/(quantity),(float)total_roundtime/(quantity));
}
//高响应比调度算法
void HRRFschdulejob() {
int i,j;
int current_time=0;
int loc;
int total_waitime=0;
int total_roundtime=0;
//输出作业流
printf("\n\nHRRF算法作业流\n");
printf("------------------------------------------------------------------------\n");
printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");
//查找最先到达的作业
current_time=INF;
for(i=0; i<quantity; i++) {
if(current_time>jobs[i].reach_time) {
current_time=jobs[i].reach_time;
}
}
//每次循环找出执行时间最短的作业并打印相关信息
for(i=0; i<quantity; i++) {
checkReached(current_time);
refreshHRR(current_time);
loc=findHRRjob(jobs,quantity);
while(loc==-1) {
current_time=INF;
for(j=0; j<quantity; j++) {
if(!jobs[j].isreached&¤t_time>jobs[j].reach_time) {
current_time=jobs[j].reach_time;
}
}
checkReached(current_time);
refreshHRR(current_time);
loc=findHRRjob(jobs,quantity);
}
if(jobs[loc].reach_time>current_time) {
jobs[loc].start_time=jobs[loc].reach_time;
current_time=jobs[loc].reach_time;
} else {
jobs[loc].start_time=current_time;
}
jobs[loc].wait_time=current_time-jobs[loc].reach_time;
printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n",jobs[loc].number,jobs[loc].reach_time,jobs[loc].start_time,jobs[loc].wait_time,
jobs[loc].wait_time+jobs[loc].need_time);
jobs[loc].visited=1;
current_time+=jobs[loc].need_time;
total_waitime+=jobs[loc].wait_time;
total_roundtime=total_roundtime+jobs[loc].wait_time+jobs[loc].need_time;
}
printf("总等待时间:%-8d 总周转时间:%-8d\n",total_waitime,total_roundtime);
printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n",(float)total_waitime/(quantity),(float)total_roundtime/(quantity));
}
//优先权高者优先调度算法
void HPF(job jobs[]) {
int i,j;
int current_time=0;
int loc;
int total_waitime=0;
int total_roundtime=0;
//输出作业流
printf("\n\nHPF算法作业流\n");
printf("------------------------------------------------------------------------\n");
printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");
//查找最先到达的作业
current_time=INF;
for(i=0; i<quantity; i++) {
if(current_time>jobs[i].reach_time) {
current_time=jobs[i].reach_time;
}
}
//每次循环找出执行时间最短的作业并打印相关信息
for(i=0; i<quantity; i++) {
checkReached(current_time);
loc=findHighPrivilegeJob();
while(loc==-1) {
current_time=INF;
for(j=0; j<quantity; j++) {
if(!jobs[j].isreached&¤t_time>jobs[j].reach_time) {
current_time=jobs[j].reach_time;
}
}
checkReached(current_time);
refreshHRR(current_time);
loc=findHRRjob(jobs,quantity);
}
if(jobs[loc].reach_time>current_time) {
jobs[loc].start_time=jobs[loc].reach_time;
current_time=jobs[loc].reach_time;
} else {
jobs[loc].start_time=current_time;
}
jobs[loc].wait_time=current_time-jobs[loc].reach_time;
printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n",jobs[loc].number,jobs[loc].reach_time,jobs[loc].start_time,jobs[loc].wait_time,
jobs[loc].wait_time+jobs[loc].need_time);
jobs[loc].visited=1;
current_time+=jobs[loc].need_time;
total_waitime+=jobs[loc].wait_time;
total_roundtime=total_roundtime+jobs[loc].wait_time+jobs[loc].need_time;
}
printf("总等待时间:%-8d 总周转时间:%-8d\n",total_waitime,total_roundtime);
printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n",(float)total_waitime/(quantity),(float)total_roundtime/(quantity));
}
int main() {
initial_jobs();
readJobdata();
FCFS();
reset_jinfo();
SFJschdulejob(jobs,quantity);
reset_jinfo();
HRRFschdulejob();
reset_jinfo();
HPF(jobs);
system("pause");
return 0;
}
动态分区分配方式模拟
#include<stdio.h>
#include<stdlib.h>
const int INF=1e7;
const int capacity=640;
typedef struct block {
int start;
int length;
int job;
block* next;
} block;
block* occupiedTable;//头指针
block* freeTable;//头指针
int job;
void Init() {
occupiedTable=(block*)malloc(sizeof(block));
occupiedTable->next=NULL;
freeTable=(block*)malloc(sizeof(block));
freeTable->next=(block*)malloc(sizeof(block));
freeTable->next->start=0;
freeTable->next->length=capacity;
freeTable->next->next=NULL;
}
void PrintOccupiedTable() {
printf("----------已分区表----------\n起始地址\t长度\t占用作业\n");
block* b=occupiedTable->next;
while(b) {
printf("%dKB\t\t%dKB\t%d\n",b->start,b->length,b->job);
b=b->next;
}
}
void PrintFreeTable() {
printf("----------空闲区表----------\n起始地址\t长度\t\n");
block* b=freeTable->next;
while(b) {
printf("%dKB\t\t%dKB\n",b->start,b->length);
b=b->next;
}
}
int AllocFirstFit(int size) {
int i,j,flag=0;
block* x;
block *p,*q,*n;
p=NULL;
n=(block*)malloc(sizeof(block));
p=freeTable;
q=occupiedTable;
while(p->next) {
//首次适应算法
if(p->next->length>=size) {
n->start=p->next->start;
n->length=size;
n->job=++job;
flag=1;
break;
} else {
p=p->next;
}
}
if(flag==0) return 0;
else {
//跟新空闲分区表
if(size==p->next->length) {
p->next=p->next->next;
} else {
p->next->start+=size;
p->next->length-=size;
}
//跟新已分区表
while(q->next&&q->next->start<n->start) q=q->next;
n->next=q->next;
q->next=n;
}
}
int AllocBestFit(int size) {
int i,j,flag=0,minFree=INF;
block* x;
block *p,*q,*n,*t;
p=NULL;
n=(block*)malloc(sizeof(block));
p=freeTable;
q=occupiedTable;
//最佳适应算法
while(p->next) {
if(p->next->length>=size&&p->next->length<minFree) {
t=p;
flag=1;
minFree=t->next->length;
}
p=p->next;
}
n->start=t->next->start;
if(flag==0) return 0;
else {
//跟新空闲分区表
if(size==t->next->length) {
t->next=t->next->next;
} else {
t->next->start+=size;
t->next->length-=size;
}
//跟新已分区表
while(q->next&&q->next->start<n->start) q=q->next;
n->length=size;
n->job=++job;
n->next=q->next;
q->next=n;
}
}
int Free(int size) {
int flag=0;
block* p,* q, *n;
p=occupiedTable;
q=freeTable;
n=(block*)malloc(sizeof(block));
while(p->next) {
if(p->next->length==size) {
flag=1;
n->start=p->next->start;
n->length=size;
p->next=p->next->next;
break;
} else {
p=p->next;
}
}
if(flag==0) return 0;
else {
while(q->next&&q->next->start<n->start) q=q->next;
//加入并合并空闲区
if(q->start+q->length==n->start) {
q->length+=n->length;
} else {
n->next=q->next;
q->next=n;
q=n;
}
if(q->next&&q->start+q->length==q->next->start) {
q->length+=q->next->length;
q->next=q->next->next;
}
}
}
int main() {
char a;
int num;
Init();
printf("*------------帮助------------*\n");
printf("| 申请大小为num的内存 a num |\n");
printf("| 释放大小为num的内存 f num |\n");
printf("| 查看已分区表 x |\n");
printf("| 查看空闲分区表 y |\n");
printf("| 退出 e |\n");
printf("*----------------------------*\n");
while(scanf("%c",&a)) {
if(a=='a') {
scanf("%d",&num);
if(!AllocBestFit(num)) {
printf("无可用内存分配!\n");
}
} else if(a=='f') {
scanf("%d",&num);
if(!Free(num)) {
printf("释放失败!\n");
}
} else if(a=='x') {
PrintOccupiedTable();
} else if(a=='y') {
PrintFreeTable();
} else if(a=='e') {
break;
} else {
printf("非法字符!\n");
}
fflush(stdin);
}
return 0;
}
/*
a 130
a 60
a 100
f 60
a 200
f 100
f 130
a 140
a 60
a 50
f 60
*/