物联网
您现在所在的位置:首页>企业动态>物联网

进程间通信

编辑:学到牛牛IT培训    发布日期: 2023-09-07 08:49:40  

进程间通信方式:

进程用户空间是相互独立的,一般而言是不能相互访问的。但很多情况下进程间需要互相通信,来完成系统的某项功能。进程通过与内核及其它进程之间的互相通信来协调它们的行为,不同进程之间进行数据交互即为进程间通信。

常见的进程间通信方式有:有名管道、无名管道、消息队列、共享内存、信号、信号量、socket。因为信号量与socket涉及到线程与网络编程的内容,所以本文不作简述。

管道:

管道分为无名管道与有名管道,无名管道是一种半双工的通信方式,数据只能单向流动且只能在具有亲缘关系的进程间使用(如:父子进程)。

有名管道也是半双工的通信方式,但允许无亲缘关系的进程间使用。

无名管道:

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/wait.h>

#include <unistd.h>


int main()

{

int fds[2] = {0}; // fds即为创建的无名管道

pipe( fds );


pid_t pid = fork();

if( pid > 0 ) {

write( fds[1], "hello", 5 ); // 父进程在fds[1]输入数据

wait( NULL );

}else if( pid == 0 ) {

char buf[10] = {0};

read( fds[0], buf, sizeof(buf) ); // 子进程在fds[0]读取数据

printf( "buf if %s ",buf );

}


return 0;

}


有名管道:(有名管道需要以指令”mkfifo+管道名”创建管道)

write.c:

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

#include <fcntl.h>


int main()

{

int fd = open( "pipeline", O_RDWR ); // 通过打开管道文件进行数据传输

if( fd < 0 )

{

perror( "pipe open error" );

return 0;

}


int ret = write( fd, "hello", 5 );

if( ret < 0 )

{

perror( "pipe write error" );

return 0;

}


close( fd );

return 0;

}


read.c:

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

#include <fcntl.h>


int main()

{

int fd = open( "pipeline", O_RDWR ); // 通过打开管道文件进行数据读取

if( fd < 0 )

{

perror( "pipe open error" );

return 0;

}


char buf[1024] = {0};

int ret = read( fd, buf, 5 );

if( ret == 0 )

{

perror( "pipe read error" );

return 0;

}

else

{

printf( "pipeline is %s ", buf );

}


close( fd );

return 0;

}


消息队列:

消息队列是消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等特点。

read.c:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <stdio.h>


struct msgbuf

{

long mtype;

char mtext[100];

};


int main()

{

int mid = msgget( 0x12345678, IPC_PRIVATE ); // 打开消息队列


struct msgbuf msg;

msgrcv( mid, &msg, sizeof(msg), 10, IPC_NOWAIT ); // 通过结构体成员mtext读取数据


printf( "%s ", msg.mtext );

return 0;

}


write.c:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <stdio.h>


struct msgbuf

{

long mtype;

char mtext[100];

};


int main()

{

int mid = msgget( 0x88888888, IPC_CREAT | IPC_PRIVATE ); // 打开消息队列


struct msgbuf msg;

msg.mtype = 10;

strcpy( msg.mtext, "hello" );


msgsnd( mid, &msg, sizeof(msg), IPC_NOWAIT ); // 通过结构体成员mtext传输数据

return 0;

}


共享内存:

共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC(进程间通信)方式,它是针对其它进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步与通信。

read.c:

#include <sys/types.h>

#include <sys/shm.h>

#include <stdio.h>


int main()

{

int id = shmget( 0x8989, 1024, IPC_CREAT ); // 创建获取ID

char *ptr = shmat( id, NULL, IPC_NOWAIT ); // 通过shmat映射内存后对共享内存进行操作

printf( "read: %s ", ptr );

shmdt( ptr ); // 删除映射

return 0;

}


write.c:

#include <sys/types.h>

#include <sys/shm.h>

#include <stdio.h>


int main()

{

int id = shmget( 0x8989, 1024, IPC_CREAT );

char *ptr = shmat( id, NULL, IPC_NOWAIT );

sprintf( ptr, "hello" );


shmdt( ptr );

return 0;

}


信号:

signal 函数作用是设置信号处理方式。signal()会依参数 signum 指定的信号编号(0~64)来设置该信号的处理函数。当指定的信号到底时,就会跳转到参数 handler 指定的函数执行。

具体信号可通过指令:kill -l查看。

#include <stdio.h>

#include <signal.h>


void handler( int sig )

{

printf( "hello " );

}


int main()

{

signal( SIGINT, handler ); // 将信号与函数关联后,只要触发信号就会执行该函数

while(1);

return 0;

}


免费试学
课程好不好,不如实地听一听

封闭学习

2

1

联系我们

电话:028-61775817

邮箱:1572396657@qq.com

地址:成都市金牛区西城国际A座8楼

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
    物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

    扫一扫,免费咨询

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
    物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

    微信公众号

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

学一流技术,找高薪工作

物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

7-24小时服务热线:

028-61775817

版权声明 网站地图

蜀ICP备2021001672号

课程问题轻松问