版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/s564200489/article/details/50506401
申请内存:
int shmget(key_t key, size_t size, int shmflg);
其中key为钥匙,两进程通过同一个钥匙找到内核中的共享内存,可通过
key_t ftok(const char *pathname, int proj_id)
得到key,也可通过强制转换自行制定数值。
size为申请共享内存空间的大小(B)
shmflg为标志
返回值为共享内存的标示符。
内存映射:
void *shmat(int shmid, const void *shmaddr, int shmflg);
其中shmid为共享内存的ID。
shmaddr为映射向进程的地址,一般填NULL让系统指配
返回值为进程内映射共享内粗的地址。
这样通过操作进程内映射地址(内存),便可以在共享内存中写入或读取数据。
但该过程是不受控制的,因此我们需要通过阻塞来控制进程的执行。
信号量
信号量与共享内存类似,也是在内核空间中申请一段内存储存数据
申请信号量:
int semget(key_t key, int nsems, int semflg);
其中 key为钥匙,两进程通过钥匙找到同一个信号量
nsems 为申请的信号量的个数
返回值为信号量标示符
操作信号量:
int semctl(int semid, int semnum, int cmd, ...);
其中semnum,为第semnum位信号量,从0开始
cmd为指定的操作
后面跟对应数据
int semop(int semid, struct sembuf *sops, unsigned nsops);
其中
struct sembuf
{
unsigned short sem_num; /* 第sem_num位信号量 */
short sem_op; /* 操作量 */
short sem_flg; /* 标志对应操作 */
}
nsops为,对nsops个信号量进行该操作
因为信号量的值不能小于0,因此可以通过semop函数进行阻塞。
实例:
输入程序:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<string.h>
int main()
{
int running =1;
int shid;
int semid;
int value;
char *sharem=NULL;
struct sembuf sem_b,sem_c;
sem_b.sem_num=1;
sem_b.sem_flg=SEM_UNDO;
sem_c.sem_num=0;
sem_c.sem_flg=SEM_UNDO;
if((semid=semget((key_t)123456,2,0666|IPC_CREAT))==-1)//申请信号量
{
perror("semget");
exit(1);
}
shid=shmget((key_t)654321,(size_t)2048,0600|IPC_CREAT);//申请共享内存
if(shid==-1)
exit(1);
sharem=shmat(shid,NULL,0);
if(sharem==NULL)
exit(1);
semctl(semid,1,SETVAL,1);//初始化将自己的信号量设为1
semctl(semid,0,SETVAL,0);//将读取进程的信号量设为0使之堵塞
while(running)
{
sem_b.sem_op=-1;//设为-1
if(semop(semid,&sem_b,1)==-1)//让信号量0加-1,若此时信号量为0则无法-1则阻塞
{
exit(1);
}
printf("write data operate\n");
printf("please input something:");
scanf("%s",sharem);
semctl(semid,0,SETVAL,1);//输入完毕将读取信号信号量置1使之不堵塞
semctl(semid,1,SETVAL,0);//将自己的信号量设为0,使自身堵塞无法再写入
if(strcmp(sharem,"end")==0)
running--;
}
shmdt(sharem);
return 0;
}
接收程序:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<string.h>
int main()
{
int running =1;
int shid;
int semid;
int value;
char *sharem=NULL;
struct sembuf sem_b,sem_c;
sem_b.sem_num=1;
sem_b.sem_flg=SEM_UNDO;
sem_c.sem_num=0;
sem_c.sem_flg=SEM_UNDO;
if((semid=semget((key_t)123456,2,0666|IPC_CREAT))==-1)
{
perror("semget");
exit(1);
}
shid=shmget((key_t)654321,(size_t)2048,0600|IPC_CREAT);
if(shid==-1)
exit(1);
sharem=shmat(shid,NULL,0);
if(sharem==NULL)
exit(1);
semctl(semid,0,SETVAL,1);
//初始化,使自己堵塞,等待输入进程的输入
while(running)
{
sem_b.sem_op=-1;
if(semop(semid,&sem_b,1)==-1)//同输入进程
{
exit(1);
}
printf("read data operate\n");
printf("%s\n",sharem);
semctl(semid,0,SETVAL,0);//将输入进程的信号量置1
semctl(semid,1,SETVAL,1);//将自己堵塞
if(strcmp(sharem,"end")==0)
running--;
}
shmdt(sharem);
if(shmctl(shid,IPC_RMID,0)!=0)//销毁共享内存
{
exit(1);
}
if(semctl(semid,0,IPC_RMID,0)!=0)//销毁信号量
{
exit(1);
}
return 0;
}