两个进程 通过共享内存 信号灯 通信(一)
实现最简单的功能 :一个读 一个写
write.c
-
//-------------------------------------
-
//两个进程通信 共享内存方式
-
//利用 信号灯 控制进程间的同步 和互斥
-
//2013-4-13
-
//-------------------------------------
-
-
#include <stdio.h>
-
#include <sys/ipc.h>
-
#include <sys/shm.h>
-
#include <sys/types.h>
-
#include <sys/sem.h>
-
#include <errno.h>
-
-
#define N 64 // sizeof buf
-
-
union semun {
-
int val; /* Value for SETVAL */
-
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
-
unsigned short *array; /* Array for GETALL, SETALL */
-
struct seminfo *__buf; /* Buffer for IPC_INFO
-
(Linux-specific) */
-
};
-
-
-
// struct of share memory
-
typedef struct share_memory
-
{
-
char buf [N];
-
}sMemory;
-
-
-
//-----creat or open the memory----- return the shmid
-
-
int crop_memory(key_t key)
-
{
-
int shmid;
-
-
if(-1 == (shmid = shmget(key, sizeof(sMemory), IPC_CREAT | IPC_EXCL | 0666)))
-
{
-
if(errno == EEXIST)
-
{
-
shmid = shmget(key, sizeof(sMemory), 0666);
-
//printf("the share memory has been created!\n");
-
return shmid; // open success ,return the shmid
-
}
-
else
-
{
-
perror("shmget");
-
return -1;
-
}
-
}
-
// else creat success
-
-
return shmid;
-
}
-
-
//------------- attached -----------
-
-
sMemory *
-
attached(int shmid)
-
{
-
sMemory * add;
-
if(NULL == (add = (sMemory *)shmat(shmid, NULL, 0))) //NULL : the system chooses a suitable (unused)
-
{ //address at which to attach the segment
-
perror("shmat");
-
return NULL;
-
}
-
-
return add;
-
}
-
-
//------- creat or open semaphore -------
-
int crop_semaphore(key_t key)
-
{
-
int semid;
-
-
if(-1 == (semid = semget(key, 2, 0666 | IPC_CREAT | IPC_EXCL )))
-
{
-
if(errno == EEXIST)
-
{
-
semid = semget(key, 2, 0666);
-
//printf("the semaphore has been created !\n");
-
}
-
else{
-
perror("semget");
-
return -1;
-
}
-
}
-
else{ // created semaphore success , inited
-
union semun u; // 0 - read ; 1 - write
-
-
u.val = 0;
-
if(-1 == semctl(semid, 0, SETVAL, u)) // set 0 - read : 0
-
{
-
perror("semctl 1");
-
return -1;
-
}
-
-
u.val = 1;
-
if(-1 == semctl(semid, 1, SETVAL, u)) //set 1-write : 1
-
{
-
perror("semctl 2");
-
return -1;
-
}
-
}
-
-
return semid;
-
}
-
-
//------------- set_wsops------------
-
void set_wsops(struct sembuf * sops)
-
{
-
sops->sem_num = 1;
-
sops->sem_op = -1;
-
sops->sem_flg = 0;
-
}
-
-
//------------- set_rsops------------
-
void set_rsops(struct sembuf * sops)
-
{
-
sops->sem_num = 0;
-
sops->sem_op = 1;
-
sops->sem_flg = 0;
-
}
-
-
//----------sem_opration------------
-
int sem_opration(int semid, struct sembuf *sops, unsigned nsops)
-
{
-
if(-1 == semop(semid, sops, nsops))
-
{
-
perror("semop");
-
return -1;
-
}
-
}
-
-
//------------- main ---------------
-
-
int main(void)
-
{
-
key_t key;
-
int shmid;
-
int semid; // the identifier of semaphore
-
sMemory * add; // the address of the attached shared memory
-
struct sembuf sops;
-
-
if(-1 == (key = ftok(".", 'l')))
-
{
-
perror("ftok");
-
return -1;
-
}
-
-
shmid = crop_memory(key); // creat or open share memory
-
add = attached(shmid); // attached
-
semid = crop_semaphore(key); //create or oen semaphore
-
-
while(1)
-
{
-
set_wsops(&sops); // p option for semaphore 1 - write
-
sem_opration(semid, &sops, 1);
-
-
fgets(add->buf, sizeof(add->buf), stdin);
-
//printf("%s", add->buf); // 若在此处读取共享内存中的数据,
-
//读放也能再读取。说明读操作没有清空内存!!!
-
-
set_rsops(&sops); // v option for semaphore o - read
-
sem_opration(semid, &sops, 1);
-
}
-
-
return 0;
-
}
read.c
-
//-------------------------------------
-
//两个进程通信 共享内存方式
-
//利用 信号灯 控制进程间的同步 和互斥
-
//2013-4-13
-
//-------------------------------------
-
-
#include <stdio.h>
-
#include <sys/ipc.h>
-
#include <sys/shm.h>
-
#include <sys/types.h>
-
#include <sys/sem.h>
-
#include <errno.h>
-
-
#define N 64 // sizeof buf
-
-
union semun {
-
int val; /* Value for SETVAL */
-
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
-
unsigned short *array; /* Array for GETALL, SETALL */
-
struct seminfo *__buf; /* Buffer for IPC_INFO
-
(Linux-specific) */
-
};
-
-
-
// struct of share memory
-
typedef struct share_memory
-
{
-
char buf [N];
-
}sMemory;
-
-
-
//-----creat_memory----- return the shmid
-
-
int crop_memory(key_t key)
-
{
-
int shmid;
-
-
if(-1 == (shmid = shmget(key, sizeof(sMemory), IPC_CREAT | IPC_EXCL | 0666)))
-
{
-
if(errno == EEXIST)
-
{
-
shmid = shmget(key, sizeof(sMemory), 0666);
-
//printf("the share memory has been created!\n");
-
return shmid; // open success ,return the shmid
-
}
-
else
-
{
-
perror("shmget");
-
return -1;
-
}
-
}
-
// else creat success
-
-
return shmid;
-
}
-
-
//------------- attached -----------
-
-
sMemory *
-
attached(int shmid)
-
{
-
sMemory * add;
-
if(NULL == (add = (sMemory *)shmat(shmid, NULL, 0))) //NULL : the system chooses a suitable (unused)
-
{ //address at which to attach the segment
-
perror("shmat");
-
return NULL;
-
}
-
-
return add;
-
}
-
-
//------- creat or open semaphore -------
-
int crop_semaphore(key_t key)
-
{
-
int semid;
-
-
if(-1 == (semid = semget(key, 2, 0666 | IPC_CREAT | IPC_EXCL )))
-
{
-
if(errno == EEXIST)
-
{
-
semid = semget(key, 2, 0666);
-
//printf("the semaphore has been created !\n");
-
}
-
else{
-
perror("semget");
-
return -1;
-
}
-
}
-
else{ // created semaphore success , inited
-
union semun u; // 0 - read ; 1 - write
-
-
u.val = 0;
-
if(-1 == semctl(semid, 0, SETVAL, u)) // set 0 - read : 0
-
{
-
perror("semctl 1");
-
return -1;
-
}
-
-
u.val = 1;
-
if(-1 == semctl(semid, 1, SETVAL, u)) //set 1-write : 1
-
{
-
perror("semctl 2");
-
return -1;
-
}
-
}
-
-
return semid;
-
}
-
-
//------------- set_wsops------------
-
void set_wsops(struct sembuf * sops)
-
{
-
sops->sem_num = 1;
-
sops->sem_op = 1;
-
sops->sem_flg = 0;
-
}
-
-
//------------- set_rsops------------
-
void set_rsops(struct sembuf * sops)
-
{
-
sops->sem_num = 0;
-
sops->sem_op = -1;
-
sops->sem_flg = 0;
-
}
-
-
//----------sem_opration------------
-
int sem_opration(int semid, struct sembuf *sops, unsigned nsops)
-
{
-
if(-1 == semop(semid, sops, nsops))
-
{
-
perror("semop");
-
return -1;
-
}
-
}
-
-
//------------- main ---------------
-
-
int main(void)
-
{
-
key_t key;
-
int shmid;
-
int semid; // the identifier of semaphore
-
sMemory * add; // the address of the attached shared memory
-
struct sembuf sops;
-
-
if(-1 == (key = ftok(".", 'l')))
-
{
-
perror("ftok");
-
return -1;
-
}
-
-
shmid = crop_memory(key); // creat or open share memory
-
add = attached(shmid); // attached
-
semid = crop_semaphore(key); //create or oen semaphore
-
-
while(1)
-
{
-
set_rsops(&sops); // p option for semaphore 1 - read
-
sem_opration(semid, &sops, 1);
-
-
//fgets(add->buf, sizeof(add->buf), stdin);
-
printf("%s", add->buf);
-
-
set_wsops(&sops); // v option for semaphore o - write
-
sem_opration(semid, &sops, 1);
-
}
-
-
return 0;
-
}
运行截图
注意:此程序没有包含共享内存的删除功能,需要人为删除。否则下次再启动程序时无法再向共享内存中写入数据。
删除共享内存方法
一: 输入命令 ipcs
二:输入 ipcrm -m shmid (此处的shmid是 如上图中的 262144)
三:输入ipcrm -s semid (此处的semid 是 上图中的 262144)
完毕
阅读(1139) | 评论(0) | 转发(0) |