在向共享内存中写数据时添加信号灯集中的灯资源(与线程中的信号量很类似,只是用一个灯代表读资源、一个灯代表写资源,并把这两个灯放在灯集(也就是数组)中)
#include
#include
#include
#include
#include
#include
#include
#include
#define PROJ_ID 'k'
#define SHM_SZ 4096
//./read /home/ubuntu
int main(int argc, const char *argv[])
{
int shmid = 0;
char *paddr;
key_t key;
pid_t pid = 0;
int semid = 0;
if(argc < 2)
{
fprintf(stderr,"Usage : %s argv[1].\n",argv[0]);
exit(EXIT_FAILURE);
}
key = ftok(argv[1],PROJ_ID);
if(key < 0)
{
perror("Fail to shmget");
exit(EXIT_FAILURE);
}
//创建共享内存
shmid = shmget(key,SHM_SZ,IPC_CREAT | 0666);
if(shmid < 0)
{
perror("Fail to shmget");
exit(EXIT_FAILURE);
}
//将共享内存映射进进程的虚拟地址空间
paddr = (char *)shmat(shmid,NULL,0);
if(paddr == (char *)-1)
{
perror("Fail to shmat");
exit(EXIT_FAILURE);
}
//初始化信号灯集,创建0和1两个读写资源
semid = init_semaphore(argv[1],2);
semid = init_semaphore(argv[1],2);
//获得共享内存映射到当前进程的地址
//向共享内存中写入数据
while(1)
{
//申请写资源(就是需要第二个灯的值为1)
P(semid,1);
putchar('>');
fgets(paddr,SHM_SZ,stdin);
paddr[strlen(paddr) - 1] = '\0';
//释放写资源:释放写灯的资源,把资源释放给读灯(两个灯,一个代表读资源,一个代表写资源)
V(semid,0);
if(strncmp(paddr,"quit",4) == 0)
break;
}
//解除映射
if(shmdt(paddr) < 0)
{
perror("Fail to shmdt");
exit(EXIT_FAILURE);
}
//由于输入了quit,read进程会删除共享内存,写进程不需要删除了
return 0;
}