1.首先复习了下,关于信号量的基本知识,我知道的借口基本有三套了,但是主要的都是解决PV操作,P为:等待,如果信号量不为0,即减1,如果为0的话,即进入等待,V:唤醒P操作等待的线程或者是进程,下面是实验中使用的接口:
//初始化
sem_t *sem_open(const char *name, unsigned int value);
//P操作
int sem_wait(sem_t *sem);
//V操作
int sem_post(sem_t *sem);
//释放
int sem_unlink(const char *name);
2)下面是自己写的生产者和消费者测试代码,注意在编译的时候,需要链接:-lpthread
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/sem.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
//联系模型生产者和消费者模型
//实现一个进程负责生产,N个进程负责消费
#define BUFFER_SIZE 10
sem_t* empty;
sem_t* full;
sem_t* mutex;
int main(void)
{
int fd_file = open("pc.log",O_CREAT|O_RDWR,0644);
empty = sem_open("empty",O_CREAT,0644,10);
full = sem_open("full",O_CREAT,0644,0);
mutex = sem_open("mutex",O_CREAT,0644,1); //可以进行生产
//将文件大小设置为0
ftruncate(fd_file,0);
//如果有这些信号量的话,先释放
sem_unlink("empty");
sem_unlink("full");
sem_unlink("mutex");
if(!fork())
{
//child producer
int i = 0;
while(i < 500)
{
i++;
sem_wait(empty);
sem_wait(mutex);
// write the data to file
lseek(fd_file,0,SEEK_END);
write(fd_file,&i,sizeof(i));
sem_post(mutex);
sem_post(full);
}
while(1);
}
if(!fork())
{
int result = 0;
int tmpResult = 0;
int fileLen = 0;
int j = 0;
//consumer
while(1)
{
sem_wait(full);
sem_wait(mutex);
//读取数据,同时将数据删除,从头开始读
lseek(fd_file,0,SEEK_SET);
read(fd_file,&result,sizeof(result));
printf("%ld:%d\n",getpid(),result);
// delete data from file
fileLen = lseek(fd_file,0,SEEK_END);
for(j = 1; j < fileLen/sizeof(result);j++)
{
lseek(fd_file,j*sizeof(result),SEEK_SET);
read(fd_file,&tmpResult,sizeof(tmpResult));
lseek(fd_file,(j - 1)*sizeof(result),SEEK_SET);
write(fd_file,&tmpResult,sizeof(tmpResult));
}
ftruncate(fd_file,fileLen - sizeof(result));
sleep(1);
sem_post(mutex);
sem_post(empty);
}
}
if(!fork())
{
int result = 0;
int tmpResult = 0;
int fileLen = 0;
int j = 0;
while(1)
{
//consumer
sem_wait(full);
sem_wait(mutex);
//读取数据,同时将数据删除,从头开始读
lseek(fd_file,0,SEEK_SET);
read(fd_file,&result,sizeof(result));
printf("%ld:%d\n",getpid(),result);
// delete data from file
fileLen = lseek(fd_file,0,SEEK_END);
for(j = 1; j < fileLen/sizeof(result);j++)
{
lseek(fd_file,j*sizeof(result),SEEK_SET);
read(fd_file,&tmpResult,sizeof(tmpResult));
lseek(fd_file,(j - 1)*sizeof(result),SEEK_SET);
write(fd_file,&tmpResult,sizeof(tmpResult));
}
ftruncate(fd_file,fileLen - sizeof(result));
sleep(1);
sem_post(mutex);
sem_post(empty);
}
}
wait(NULL);
}