卡卡西至 https://blog.csdn.net/ccshijtgc/article/details/60327130
sem.c
#define __LIBRARY__
#include <unistd.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <asm/segment.h>
#include <asm/system.h>
sem_t *sem_head = &((sem_t *){"\0",0,NULL,NULL});
sem_t *sys_sem_open(const char *name,int value){
char pname[SEM_NAME_LEN];
sem_t *sem_cur,*sem_pre;
//获取用户态字符串
char c;
int i;
for(i=0;(c=get_fs_byte(name++))!='\0' && i<SEM_NAME_LEN;i++)
pname[i]=c;
pname[i]='\0';
//查看是否存在
for(sem_pre=sem_head,sem_cur=sem_head->next ;sem_cur&&strcmp(pname,sem_cur->name);sem_pre=sem_cur,sem_cur=sem_cur->next)
//新建一个
if(!sem_cur){
printk("semaphore %s no found. created a new one. \n", pname);
sem_cur = (sem_t *)malloc(sizeof(sem_t));
strcpy(sem_cur->name,pname);
sem_cur->value = value;
sem_cur->next =NULL;
sem_pre->next = sem_cur;
}
printk("pid %d opens semaphore %s(value %u) OK. \n", current->pid, pname, sem_cur->value);
return sem_cur;
}
int sys_sem_wait(sem_t *sem){
//关中断
cli();
//<=0sLEEP
while(sem->value<=1)
sleep_on(&(sem->s_wait));
//--
sem->value--;
//开中断
sti();
return 0;
}
int sys_sem_post(sem_t *sem){
sem->value++;
if(sem->value>0){
wake_up(&(sem->s_wait));
return 0;
}
return -1;
}
int sys_sem_unlink(const char *name){
char pname[SEM_NAME_LEN];
sem_t *sem_cur,*sem_pre;
//获取用户态字符串
char c;
int i;
for(i=0;(c=get_fs_byte(name++))!='\0' && i<SEM_NAME_LEN;i++)
pname[i]=c;
pname[i]='\0';
//查看是否存在
for(sem_pre=sem_head,sem_cur=sem_head->next ;sem_cur&&strcmp(pname,sem_cur->name);sem_pre=sem_cur,sem_cur=sem_cur->next)
//不存在
if(!sem_cur)
return -1;
//存在
sem_pre->next = sem_cur->next;
free(sem_cur);
printk("unlink semaphore %s OK. \n", pname);
return 0;
}
PC.C
#include <stdio.h>
#include <stdlib.h>
#define __LIBRARY__
#include <unistd.h>
_syscall2(sem_t *,sem_open,const char *,name,int,value);
_syscall1(int,sem_wait,sem_t *,sem);
_syscall1(int,sem_post,sem_t *,sem);
_syscall1(int,sem_unlink,const char *,name);
#define CONSUMERS 5
#define PRODUCER 50
#define BUFFSIZE 10
int item_pro,item_used;
sem_t *empty,*full,*mutex;
int main(){
int pid;
int i;
int fi;
int fo;
fi = open("buff.dat",O_CREAT|O_TRUNC|O_WRONLY,0222);
fo = open("buff.dat",O_TRUNC|O_RDONLY,0444);
mutex = sem_open("mutex",1);
full = sem_open("full",0);
empty = sem_open("empty",BUFFSIZE);
if((pid=fork()))
{
printf("pid %d:\tproducer created....\n", pid);
fflush(stdout);
while(item_pro<=PRODUCER){
printf("debug1\n");
sem_wait(empty);
printf("debug2\n");
sem_wait(mutex);
printf("debug3\n");
if(!(item_pro % BUFFSIZE))
lseek(fi, 0, 0);
write(fi, (char *) &item_pro, sizeof(item_pro)); /* 写入产品编号 */
printf("pid %d:\tproduces item %d\n", pid, item_pro);
fflush(stdout);
item_pro++;
sem_post(mutex);
sem_post(full);
}
}else{
i = CONSUMERS;
while(i--){
if((pid=fork())==0){
pid = getpid();
printf("pid %d:\tconsumer %d created....\n", pid, CONSUMERS-i);
fflush(stdout);
while(1){
sem_wait(full);
sem_wait(mutex);
/*read()读到文件末尾时返回0,将文件的位置指针重新定位到文件首部 */
if(!read(fo, (char *)&item_used, sizeof(item_used)))
{
lseek(fo, 0, 0);
read(fo, (char *)&item_used, sizeof(item_used));
}
printf("pid %d:\tconsumer %d consumes item %d\n", pid, CONSUMERS-i+1, item_used);
fflush(stdout);
sem_post(mutex);
sem_post(empty);
if(item_used==PRODUCER)
goto OK;
}
}
}
}
OK:
sem_unlink("empty");
sem_unlink("full");
sem_unlink("mutex");
close(fi);
close(fo);
return 0;
}
结果