#include
#include
#include
#include
#include
#include
#include
#include
#define SHM_SIZE 1024 //共享内存的大小
int main(int argc,char *argv[])
{
int ret, //临时变量
pid, //进程id
sme_id, //保存信号量描述符
shm_id; //保存共享内存描述符
key_t sme_key, //保存信号量键值
shm_key; //保存共享内存键值
char *shmp; //指向共享内存的首地址
struct shmid_ds dsbuf; //定义共享内存信息结构变量
struct sembuf lock = {0, -1, SEM_UNDO}; //信号量上锁操作的数组指针
struct sembuf unlock = {0, 1, SEM_UNDO | IPC_NOWAIT};//信号量解锁操作的数组指针
shm_key = ftok(*(argv+1), 2); //获取信号量键值
if(shm_key < 0)
{
perror("ftok"); //调用ftok函数出错
exit(0);
}
sme_id = semget(shm_key, 1, IPC_CREAT | 0666); //获取信号量ID
if(sme_id < 0)
{
perror("semget"); //调用semget函数出错
exit(0);
}
shm_key = ftok(*(argv+2), 1); //获取共享内存键值
if(shm_key < 0)
{
perror("ftok");
exit(0);
}
shm_id = shmget(shm_key, SHM_SIZE, IPC_CREAT | 0666); //获取共享内存ID
if(shm_id < 0)
{
perror("shmget");
exit(0);
}
shmp = shmat(shm_id, NULL, 0); //映像共享内存
if((int)shmp == -1)
{
perror("shmat");
exit(0);
}
pid = fork(); //创建子进程
if(pid < 0)
{
perror("fork");
exit(0);
}
else if(pid == 0) //子进程
{
ret = semctl(sme_id, 0, SETVAL, 1); //初始化信号量,初值设为1
if(ret == -1)
{
perror("semctl");
exit(0);
}
ret = semop(sme_id, &lock, 1); //申请访问共享资源,锁定临界资源
if(ret == -1)
{
perror("semop lock");
exit(0);
}
sleep(4); //让子进程睡眠4秒
strcpy(shmp, "hello\n"); //往共享内存写入数据
if(shmdt((void *)shmp) < 0) //使共享内存脱离进程地址空间
{
perror("shmdt");
}
ret = semop(sme_id, &unlock, 1); //解锁临界资源
if(ret == -1)
{
perror("semop unlock");
exit(0);
}
}
else //父进程
{
sleep(1); //先让子进程运行
ret = semop(sme_id, &lock, 1); //申请访问共享资源,锁定临界资源
if(ret == -1)
{
perror("semop lock");
exit(0);
}
if(shmctl(shm_id, IPC_STAT, &dsbuf) < 0) //获取共享内存信息
{
perror("shmctl");
exit(0);
}
else /* 共享内存的状态信息获取成功 */
{
printf("Shared Memory Information:\n");
printf("\tCreator PID: %d\n", dsbuf.shm_cpid); /* 输出创建共享内存进程的标识符 */
printf("\tSize(bytes): %d\n",dsbuf.shm_segsz); /* 输出共享内存的大小 */
printf("\tLast Operator PID: %d\n",dsbuf.shm_lpid); /* 输出上一次操作共享内存进程的标识符 */
printf("Received message : %s\n", (char *)shmp); /* 从共享内存中读取数据 */
}
if(shmdt((void *)shmp) < 0) //使共享内存脱离进程地址空间
{
perror("shmdt");
exit(0);
}
ret = semop(sme_id, &unlock, 1); //解锁临界资源
if(ret == -1)
{
perror("semop unlock");
exit(0);
}
if(shmctl(shm_id, IPC_RMID, NULL) < 0) /* 删除前面创建的共享内存 */
{
perror("shmctl");
exit(0);
}
ret = semctl(sme_id, 0, IPC_RMID, NULL); //删除信号量
if(ret == -1)
{
perror("semctl");
exit(0);
}
}
return 0;
}
本文标题:[Linux管道和IPC]使用信号量和共享内存进行父子进程通信
标题来源:
http://chengdu.cdxwcx.cn/article/pgodoc.html