无亲缘关系的进程间进行通信在shmget中不能使用IPC_PRIVATE,这样创建的shmid都是0,只能用于有亲缘关系的进程。无亲缘关系的只能通过ftok创建一个key值来用。
但是两个进程间通过kill发送信号需要知道pid号,只能是先server创建,将自己的pid存到共享内存中,然后client读取共享内存中server的pid,再将client的pid存到共享内存,server再读取。
server
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <signal.h>
struct mybuf
{
int pid;
char buf[124];
};
void myfun(int signum)
{
return;
}
int main()
{
int shmid;
int key;
struct mybuf *p;
int pid;
key = ftok("a.c", 'a');
if (key < 0)
{
printf("cerat key error\n");
return -1;
}
printf("creat key successfully\n");
shmid = shmget(key, 128, IPC_CREAT |0777);
if (shmid < 0)
{
printf("cerat shm error\n");
return -2;
}
printf("creat shm successfully, shmid = %d\n", shmid);
signal(SIGUSR2,myfun); //要对client来的2信号进行处理,不处理的话默认终止
p = (struct mybuf *)shmat(shmid, NULL, 0);
if (p == NULL)
{
printf("shmat error\n");
return -3;
}
p->pid = getpid(); //write server pid to share memory
pause(); //wait client read server pid
pid = p->pid;
while(1)
{
printf("client process start write share memory\n");
fgets(p->buf, 128, stdin);
kill(pid, SIGUSR1); //client process read data
pause(); //wait client process read
}
shmdt(p);
shmctl(shmid, IPC_RMID, NULL);
system("ipcs -m");
return 0;
}
client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <signal.h>
struct mybuf
{
int pid;
char buf[124];
};
void myfun(int signum)
{
return;
}
int main()
{
int shmid;
int key;
struct mybuf *p;
int pid;
key = ftok("a.c", 'a');
if (key < 0)
{
printf("cerat key error\n");
return -1;
}
printf("creat key successfully\n");
shmid = shmget(key, 128, IPC_CREAT |0777);
if (shmid < 0)
{
printf("cerat shm error\n");
return -2;
}
printf("creat shm successfully, shmid = %d\n", shmid);
signal(SIGUSR1,myfun);//要对server来的1信号进行处理
p = (struct mybuf *)shmat(shmid, NULL, 0);
if (p == NULL)
{
printf("shmat error\n");
return -3;
}
pid = p->pid; //read server pid
p->pid = getpid(); //write client pid
kill(pid, SIGUSR2); //
while(1)
{
pause(); //wait server write data
printf("client process start read share memory:%s", p->buf);
kill(pid, SIGUSR2);
}
shmdt(p);
shmctl(shmid, IPC_RMID, NULL);
system("ipcs -m");
return 0;
}