详解linux下的进程通信,Linux 下的进程间通信

一、管道(先进先出)

1、创建管道

#include int pipe(int filed[2])

filed[0]是以读方式打开,filed[1]是以写方式打开

在同一个进程中使用管道是没有意义的,一般在创建管道后进程要调用fork,然后在父进程和子进程间进行通信。

管道中的数据容量是有限制的,/usr/include/linux/limits.h

PIPE_BUF = 4096

表明任一时刻管道中的数据量不能超过4096字节, 否则write会堵塞和直接返回0

例)

#include

#include

#include

int main()

{

int fd[2], nbytes;

pid_t childpid;

char string[] = "data from child process/n";

char readbuffer[32];

if(pipe(fd) < 0)

{

perror("pipe");

exit(1);

}

if((childpid = fork()) == -1)

{

perror("fork");

exit(1);

}

if(0 == childpid)

{//子进程

/*子进程关闭读管道*/

close(fd[0]);

/*向管道的写端口写入字符*/

wirte(fd[1], string, strlen(string));

exit(0);

}

else

{

/*父进程关闭写端口*/

close(fd[1]);

nbytes = read(fd[0], readbuffer, sizeof(readbuffer));

printf("Received string: %s", readbuffer);

}

return 1;

}

二、使用管道的基本套路

1、创建管道;

2、调用fork,创建子进程;

3、在子进程中把管道文件描述符复制到标准输入或输出文件号,并关闭多余的文件描述符;

if(fork() == 0)

{

close(0);/*关闭标准输入文件描述符*/

dup(fd[0]);/*复制管道的输入端到标准输入*/

close(fd[0]);/*关闭多余的管道描述符*/

close(fd[1]);/*次处不使用管道的写入端*/

...

...

exit(0);

}

4、子进程exec其他应用程序

5、父进程也关闭一个多余的管道文件描述符;

6、父子进程读写管道;

7、父进程等待子进程终止。

三、可以使用popen代劳二的工作

#include

FILE * popen(const char * cmdstring, const char *type);

#include

int pclose(FILE *fp);

四、流管道(全双工管道), 可惜linux系统不支持

五、FIFO(命名管道)

两者之间的通信只要认可一个文件名既可,而不需要有集成关系

1、创建

#include

#include

int mkfifo(const char *pathname, mode_t mode);

2、打开

fopen("filename", "mode");

例)

//filo_s.c

int main()

{

int fdserver;

int fdclient;

pid_t cpid, spid;

char client_fifo_name[32];

mkfifo(SERVER_FIFO_NAME, 0660);

if((fdserver = open(SERVER_FIFO_NAME, O_RDWR)) == -1)

{

printf("Server:Can't open fifo/n");

fflush(stdout);

exit(1);

}

spid = getpid();

while(1)

{

/*读取客户进程pid并生成客户的FIFO文件名*/

read(fdserver, &cpid, sizeof(pid_t));/*阻塞,直到客户进程写入*/

sprintf(client_fifo_name, CLIENT_FIFO_NAME, cpid);

/*向客户fifo管道写入服务进程pid*/

if((fdclient = open(client_fifo_name, O_WRONLY)) == -1)

continue;

write(fdclient, &spid, sizeof(pid_t));

close(fdclient);

}

return 1;

}

//fifo_c.c

int main()

{

int fdserver;

int fdclient;

pid_t cpid, spid;

char client_fifo_name[32];

/*打开服务器FIFO管道*/

if((fdserver = open(SERVER_FIFO_NAME, O_WRONLY)) == -1)

{

printf("server not active/n");

exit(0);

}

/*创建并打开客户FIFO管道*/

cpid = getpid();

sprintf(client_fifo_name, CLIENT_FIFO_NAME, cpid);

mkfifo(client_fifo_name, 0660);

if((fdclient = open(client_fifo_name, O_RDWR)) == -1)

{

close(fdserver);

printf("can't open fifo/n");

exit(0);

}

/*写入自身pid,读出服务器pid*/

write(fdserver,&cpid, sizeof(pid_t));

/*阻塞,知道服务器进程写入*/

read(fdclient, &spid, sizeof(pid_t));

printf("client: get server pid :%d/n", spid);

close(fdserver);

close(fdclient);

unlink(client_fifo_name);

return 1;

}

六、System V IPC    消息队列、信号量、共享内存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值