您的位置:首页 > 其它

使用共享内存实现进程间通信 -使用信号实现同步

2017-07-16 16:06 344 查看
今天,给大家分享一下共享内存实现通信,使用信号实现同步。

1. 进程的创建

1)对于进程的创建,使用的函数为fork();

函数原型为pid_t fork(void);

即可在父进程中创建子进程

头文件:#include <sys/types.h>
#include <unistd.h>


返回值:-1 出错;
0 :子进程;
子进程的PID(大于0的整数): 父进程
子进程创建成功之后,就会有自己独立的内存空间,会拷贝父进程内存空间中几乎所有的内容。
在这里运行程序时,子进程和父进程会同时去去抢占系统资源,抢占到系统资源的几率相等,所以可以得出父进程和子进程执行的顺序是不确定的,所以这里我们使用信号实现同步,在子进程中使用raise()函数,向自己发送一个SIGSTOP的信号,使子进程暂停;在父进程中调用watpid()函数等待子进程是否结束,如果没有结束,则使用kill(pid,SIGCONT)函数向子进程发送继续执行信号,即可实现同。
说一下两个函数,getpid();得到自己进程号,
getppid();得到父进程的进程号


下面这个代码是关于父子进程通信的实现

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
int main()
{
key_t key = ftok(".",15);
if(key<0)
{
perror("ftok error");
return -1;
}

int shm=shmget(key,1024,IPC_CREAT|0666);
if(shm<0)
{
perror("shmget error");
return -1;
}
char *p = (char *)shmat(shm,NULL,0);
if((char *)-1 == p)
4000
{
return -1;
}

pid_t pid = fork();
if(pid<0)
{
perror("fork error");
return -1;
}
else if(pid == 0)
{
while(1)
{
if(*p!=0)
{
printf("from 十号:%s\n",p);
}
memset(p,0,1024);

printf("库里:");
gets(p);
sleep(5);
raise(SIGSTOP);
}
}
else //waitpid函数 在父进程中返回的是子进程的ID
{
while(1)
{
sleep(5);
if((waitpid(pid,NULL,WNOHANG))==0)
{
if(*p!=0)
{
printf("from 库里:%s\n",p);
}
memset(p,0,1024);
printf("十号:");
gets(p);
sleep(5);
kill(pid,SIGCONT);
}
}
}
shmdt(p);
shmctl(shm,IPC_RMID,NULL);
return 0;
}


接下来是不同进程之间的通信-使用共享内存以及信号实现同步。

源码pro-chat3.c如下:

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#include <stdlib.h>

void funXLD(int sign)
{

}
int main()
{
//创建共享内存
key_t key =ftok(".",12);
if(key<0)
{
perror("ftok error");
return -1;
}
int ret = shmget(key,1024,IPC_CREAT | 0666);
if(ret<0)
{
perror("shmget error");
return -1;
}
char *p = shmat(ret,NULL,0);
if((char *)-1 == p)
{
perror("shmat error");
return -1;
}
signal(SIGUSR1,funXLD);

pid_t pid2 =getpid();
pid_t pid = *(int *)p;//从内存中获取进程的ID

memset(p,0,1024);
*(int *)p = pid2; //将自己的ID放入内存
kill(pid,SIGUSR1);
printf("已接通,等待詹姆斯说话\n");
while(1)
{
pause();
if(*p != 0)
{
printf("from 詹姆斯:%s\n",p);
}
memset(p,0,1024);
printf("库里:");
gets(p);
if(strcmp(p,"#")==0)
{
kill(pid,SIGABRT);
shmdt(p);
shmctl(ret,IPC_RMID,NULL);
exit(0);
}
kill(pid,SIGUSR1);
}
shmdt(p);
shmctl(ret,IPC_RMID,NULL);
return 0;
}


pro-chat4.c如下

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#include <stdlib.h>

void funXLD (int sign)
{

}
int main()
{
//创建共享内存
key_t key =ftok(".",12);
if(key<0)
{
perror("ftok error");
return -1;
}
int ret = shmget(key,1024,IPC_CREAT | 0666);
if(ret<0)
{
perror("shmget error");
return -1;
}
char *p = shmat(ret,NULL,0);
if((char *)-1 == p)
{
perror("shmat error");
return -1;
}
signal(SIGUSR1,funXLD);

pid_t pid = getpid();
memset(p,0,1024);
*(int *)p = pid;
printf("连接中。。。\n");
pause();
printf("连接成功\n");
pid = *(int *)p;
while(1)
{
memset(p,0,1024);
printf("詹姆斯:");
gets(p);
if(strcmp(p,"#")==0)
{
kill(pid,SIGABRT);
shmdt(p);
shmctl(ret,IPC_RMID,NULL);
exit(0);
}
kill(pid,SIGUSR1);
pause();
if(p!=NULL)
{
printf("from 库里:%s\n",p);
}

}
shmdt(p);

return 0;
}


有兴趣的可以试试,希望大家可以常来看我的博客。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: