操作系统:信号量机制之生产者与消费者实验

操作系统:信号量机制之生产者与消费者实验 

实验目的:了解和熟悉linux系统下的信号量集和共享内存。

任务使用linux系统提供的信号量集和共享内存实现生产者和消费者问题。

实验要求:

  1. 写两个程序,一个模拟生产者过程,一个模拟消费者过程;
  2. 创建一个共享内存模拟生产者-消费者问题中缓冲队列,该缓冲队列有N(N=10)个缓冲区,每个缓冲区的大小为1024B,每个生产者和消费者对缓冲区必须互斥访问;
  3. 由第一个生产者创建信号量和共享内存,其他生产者和消费者可以使用该信号量和共享内存;
  4. 生产者程序:生产者生产产品(即是从键盘输入长度小于1024B的字符)放入空的缓冲区;
  5. 消费者程序:消费者消费产品(即从满的缓冲区中取出内容在屏幕上打印出来),然后满的缓冲区变为空的缓冲区;
  6. 多次运行生产者程序和消费者进程,可以产生多个生产者进程和多个消费者进程,这些进程可以共享这些信号量和共享内存,实现生产者和消费者问题;
  7. 在生产者程序和消费者程序中,都可以选择:
    1. 生产产品/消费产品;
    2. 退出。退出进程,但信号量和共享内存仍然存在,其他生产者进程和消费者进程还可以继续使用;
    3. 删除信号量和共享内存。显性删除信号量和共享内存,其他生产者进程和消费者进程都不能使用这些信号量和共享内存。

 

代码:

环境:Linux,需要将头文件对应的c文件,和另外两个主要的c程序分别联合编译。

如:gcc pubfun.c producer.c -o producer

文件1:shm_sem.h

# ifndef _SHM_SEM_H
# define _SHM_SEM_H
# define N 10   
# define SHM_KEY 38111
# define SEM_KEY 38222
# define SHM_SIZE (1024*(N+1)) 
# define SEM_NUM  3
 
int sem_p(int semid, int semnum);
int sem_v(int semid, int semnum);
int get_semval(int semid, int semnum);
 
union semun
{
	int val;                 /*for SETVAL*/
	struct semid_ds *buf;    /*for IPC_STAT  ans  IPC_SET*/
	unsigned short *array;   /*for GETALL  ans  SET_ALL*/
}; 
 
# endif

文件二:pubfun.c

#include   
#include   
#include   
#include  
#include  
#include   
#include   
#include  
 
/*sem P*/
int sem_p(int semid, int semnum)
{
	/**********************************************
	* name:		sem_p(int semid, int semnum)
	* description:进行p操作 
	* paras:	semid:信号量的标识符,也就是semget()函数的返回值	semnum:操作的信号在信号集中的编号
	* return:	semop的返回值 
	***********************************************/
	
	
	/*int semop(int semid, struct sembuf semoparray[], size_t cnts); */
	/**********************************************
	* name:		semop(int semid, struct sembuf semoparray[], size_t cnts)
	* description: 用户改变信号量的值。也就是使用资源或释放资源。对信号量集标识符为semid中的一个或多
个信号量进行P操作或V操作。
	* paras:	semid, sembuf semoparray[]:指向进行操作的信号量集结构体数组 	cnts:进行操作的信号量个数,常为1
	*struct sembuf{
		short sem_num; //信号量集合中的信号量编号,0代表第1个信号量
		short sem_op; 	//若sem_op大于0,进行v操作,信号量值加sem_op,表示进程释放控制的资源
				   	//若sem_op小于0,进行p操作,信号量值减sem_op,若(semval-sem_op)<0 (semval为该信号量值),进程阻塞直到资源可用
					//sem_op==0时,调用进程进入睡眠状态,直到信号值为0.
		short flag; // “0”设置信号量的默认操作
					//IPC_NOWAIT 设置信号量操作不等待
					//SEM_UNDO 选项会让内核记录一个与调用进程相关的UNDO记录,如果该进程崩溃,则根据这个进程的UNDO记录自动恢复相应信号量的计数值
	} 
	* return:	成功返回信号量集的标识符,失败返回-1

你可能感兴趣的:(操作系统,C语言,信号量,生产者消费者,操作系统)