#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/sem.h>
#include "structs.h"
/*typedef struct{
char name[10];
int age;
}People;
*/
//声明联合体
union semun{
int val;
struct semid_ds *buf;
unsigned short int *array;
};
int main(int argc,char **argv){
SHM *p_map;
int shm_id;
int i;
char temp;
int key;
//People *p_map;
char *name = "/dev/shm/myshm2";
int value;
int sem_id;
union semun options;
struct sembuf lock_it;
key = ftok(name,0); //获得key值,用到了ftok函数
if (key==-1){
perror("ftok error");
}
sem_id = semget(key,1,IPC_CREAT|0666); //通过key获得信号量id
printf("sem_id=%d/n",sem_id);
if(-1==sem_id){
printf("create semaphore error/n");
exit(-1);
}
options.val =1; //操作联合体,使得初始的信号量为1
semctl(sem_id,0,SETVAL,options); //设置索引为0的位置的信号量
i = semctl(sem_id,0,GETVAL,options); //获取 索引为 0的 位置的信号量 i
printf("%d/n",i);
shm_id = shmget(key,1024,IPC_CREAT); //通过key及是shmget函数创建共享内存
if (shm_id == -1){
perror("shmget error");
return;
}
p_map =(SHM*)shmat(shm_id,NULL,0); //通过shmat操作共享内存
lock_it.sem_num =0; //操作信号量,使信号量减一变成0
lock_it.sem_op = -1;
lock_it.sem_flg = IPC_NOWAIT;
semop(sem_id,&lock_it,1);
i = semctl(sem_id,0,GETVAL,0); //得到信号量为0
printf("xiu gai hou de i %d/n",i);
p_map =(SHM*)shmat(shm_id,NULL,0);
strcpy(p_map->chara,"zhangsan"); //对 共享内存中的结构体进行操作
p_map->inta=20;
printf("%d/n",p_map->inta);
printf("%s/n",p_map->chara);
lock_it.sem_num = 0; //操作完毕后 信号量加1 ,便于其他进程使用
lock_it.sem_op = +1;
lock_it.sem_flg = IPC_NOWAIT;
semop(sem_id,&lock_it,1);
i = semctl(sem_id,0,GETVAL,0);
printf("zai ci xiu gai hou de i %d/n",i);
//if (shmdt(p_map)==-1){
// perror("detach error");
//};
//exit(0);
}
或者可以把以上程序看成是一个 服务器 ,接下来写一个读共享内存中数据的客户端
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/sem.h>
#include "structs.h"
/*typedef struct{
char name[10];
int age;
}People;
*/
union semun{
int val;
struct semid_ds*buf;
unsigned short *array;
};
main(int argc,char** argv){
int shm_id;
int i;
int sem_id;
key_t key;
SHM *p_map;
// p_map = (SHM*)malloc(sizeof(People));
union semun options;
struct sembuf lock_it;
char *name = "/dev/shm/myshm2";
key = ftok(name,0);
if(key==-1){
perror("ftok error/n");
}
sem_id = semget(key,0,0); //对已存在 信号量进行操作,参数不一样 ,是0,0
semctl(sem_id,0,SETVAL,options);
i = semctl(sem_id,0,GETVAL,0);
shm_id = shmget(key,0,0); //对已存在的共享内存进行操作,参数与创建共享内存时不一样
if(shm_id == -1){
perror("shmget error/n");
return;
}
lock_it.sem_num = 0; //等待函数,等到flg为1时,即信号量为1时,才能对共享内存进行操作
lock_it.sem_op = 0;
lock_it.sem_flg = 1;
semop(sem_id,&lock_it,1);
i = semctl(sem_id,0,GETVAL,0);
while(1){
if(i==1){
lock_it.sem_num = 0; //当判断信号量 i ==1 时,进入共享内存,并马上操作信号量-1变成0,使得其他进程阻塞
lock_it.sem_op = -1;
lock_it.sem_flg = IPC_CREAT;
semop(sem_id,&lock_it,1);
// p_map = (SHM*)malloc(sizeof(SHM));
p_map = (SHM*)shmat(shm_id,NULL,0);
//p_map = (People*)malloc(sizeof(People));
printf("%s/n",p_map->chara); //读取共享内存中的数据
printf("%d/n",p_map->inta);
lock_it.sem_num = 0; //读取完毕后,再把信号量加1,便于其他进程使用
lock_it.sem_op = 1;
lock_it.sem_flg = IPC_CREAT;
semop(sem_id,&lock_it,1);
exit(0);
}else{
continue; // 如果信号量不为0,则继续等待
}
}
}