修改工程文件的编译规则
文件位置:oslab/linux0.11/kernel/Makefile
进入主文件开始编译,编译完成。
编写消费者和生产者程序
sudo ./mount-hdc cd /oslab/hdc/usr/root vi producer.c vi consumer.c sudo umount hdc/
编写producer.c
/*producer.c*/ #define __LIBRARY__ #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <linux/sem.h> _syscall2(sem_t*,sem_open,const char *,name,unsigned int,value); _syscall1(int,sem_wait,sem_t*,sem); _syscall1(int,sem_post,sem_t*,sem); _syscall1(int,sem_unlink,const char *,name); _syscall1(void*,shmat,int,shmid); _syscall2(int,shmget,int,key,int,size); /*_syscall1(int,shmget,char*,name);*/ #define NUMBER 520 /*打出数字总数*/ #define BUFSIZE 10 /*缓冲区大小*/ sem_t *empty, *full, *mutex; int main() { int i,shmid; int *p; int buf_in = 0; /*写入缓冲区位置*/ /*打开信号量*/ if((mutex = sem_open("mutex",1)) == NULL) { perror("sem_open() error!\n"); return -1; } if((empty = sem_open("empty",10)) == NULL) { perror("sem_open() error!\n"); return -1; } if((full = sem_open("full",0)) == NULL) { perror("sem_open() error!\n"); return -1; } /*shmid = shmget("buffer");*/ shmid = shmget(1234, BUFSIZE); printf("shmid:%d\n",shmid); if(shmid == -1) { return -1; } p = (int*) shmat(shmid); /*生产者进程*/ printf("producer start.\n"); fflush(stdout); for( i = 0 ; i < NUMBER; i++) { sem_wait(empty); sem_wait(mutex); p[buf_in] = i; buf_in = ( buf_in + 1)% BUFSIZE; sem_post(mutex); sem_post(full); } printf("producer end.\n"); fflush(stdout); /*释放信号量*/ sem_unlink("full"); sem_unlink("empty"); sem_unlink("mutex"); return 0; }
编写consumer.c
/*consumer.c*/ #define __LIBRARY__ #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <linux/sem.h> _syscall2(sem_t*,sem_open,const char *,name,unsigned int,value); _syscall1(int,sem_wait,sem_t*,sem); _syscall1(int,sem_post,sem_t*,sem); _syscall1(int,sem_unlink,const char *,name); _syscall1(void*,shmat,int,shmid); _syscall2(int,shmget,int,key,int,size); #define NUMBER 520 /*打出数字总数*/ #define BUFSIZE 10 /*缓冲区大小*/ sem_t *empty, *full, *mutex; int main() { int i,shmid,data; int *p; int buf_out = 0; /*从缓冲区读取位置*/ /*打开信号量*/ if((mutex = sem_open("mutex",1)) == NULL) { perror("sem_open() error!\n"); return -1; } if((empty = sem_open("empty",10)) == NULL) { perror("sem_open() error!\n"); return -1; } if((full = sem_open("full",0)) == NULL) { perror("sem_open() error!\n"); return -1; } printf("consumer start.\n"); fflush(stdout); /*shmid = shmget("buffer");*/ shmid = shmget(1234, BUFSIZE); printf("shmid:%d\n",shmid); if(shmid == -1) { return -1; } p = (int *)shmat(shmid); for( i = 0; i < NUMBER; i++ ) { sem_wait(full); sem_wait(mutex); data = p[buf_out]; buf_out = (buf_out + 1) % BUFSIZE; sem_post(mutex); sem_post(empty); /*消费资源*/ printf("%d: %d\n",getpid(),data); fflush(stdout); } printf("consumer end.\n"); fflush(stdout); /*释放信号量*/ sem_unlink("full"); sem_unlink("empty"); sem_unlink("mutex"); return 0; }
运行验证
报错原因找了好久,感觉该干的事情都干了。最后看到这篇文章添加了__NR_whoami编译还是不行,才恍然大悟。
将已经修改的 unistd.h 拷贝到linux-0.11系统中
sudo ./mount-hdc cp ./linux-0.11/include/unistd.h ./hdc/usr/include/ sudo umount hdc/
开始正式运行程序:
gcc -o producer producer.c gcc -o consumer consumer.c ./producer > p.txt & ./consumer > c.txt
这个不影响。直接关闭虚拟机,挂载后查看 p.txt 和 c.txt
😉 实验成功!