多线程GCD 队列 异步 网络 socket block 循环引用多线程Linux 相关文章

进程间通信

2016-08-15  本文已影响40人  狼之足迹

每个进程都有各自的进程地址空间,所以进程之间的交互就需要通过内核了.

进程间通信方式:

管道

命名管道

XSI IPC:

消息队列

信号量

共享内存


管道pipe

int pipe(int pipe fd[2]);

fd[0]    读文件描述符

fd[1]    写文件描述符

父进程创建管道,fork[子进程获得父进程打开的描述符]

管道只能实现单方向通信;

且因为实现,仅能父子进程间通信.或者同宗族进程通信,且其必须从公共祖先获得管道

命名管道

在文件系统中创建一个管道文件.使得进程都可以访问得到

shell方式创建命名管道

mknod - make block or character special files

mkfifo - make FIFOs (named pipes)

函数创建

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

int mkfifoat(int dirfd, const char *pathname, mode_t mode);

XSI IPC


消息队列

消息队列提供了一种向另一进程发送数据块的方法

消息队列是基于消息的,而管道是基于字节流的

lang@liang:~$ cat /proc/sys/kernel/msgmax  最大长度
8192
lang@liang:~$ cat /proc/sys/kernel/msgmnb 每个消息的总字节数
16384
lang@liang:~$ cat /proc/sys/kernel/msgmni  消息队列的总数
32000

内核为IPC维护的数据结构,消息队列,信号量,共享内存都有一个以下的数据类型

#cat /usr/include/linux/ipc.h

IPC对象数据结构

struct ipc_perm
{
__kernel_key_t key;
__kernel_uid_t uid;
__kernel_gid_t gid;
__kernel_uid_t cuid;
__kernel_gid_t cgid;
__kernel_mode_t mode;
unsigned short seq;
};

msg对象数据结构

struct msqid_ds {

struct ipc_perm msg_perm;

struct msg *msg_first; /* first message on queue,unused  */

struct msg *msg_last; /* last message in queue,unused */

__kernel_time_t msg_stime; /* last msgsnd time */

__kernel_time_t msg_rtime; /* last msgrcv time */

__kernel_time_t msg_ctime; /* last change time */

unsigned long  msg_lcbytes; /* Reuse junk fields for 32 bit */

unsigned long  msg_lqbytes; /* ditto */

unsigned short msg_cbytes; /* current number of bytes on queue */

unsigned short msg_qnum; /* number of messages in queue */

unsigned short msg_qbytes; /* max number of bytes on queue */

__kernel_ipc_pid_t msg_lspid; /* pid of last msgsnd */

__kernel_ipc_pid_t msg_lrpid; /* last receive pid */

};

相应函数

int msgget(key_t key, int msgflg)  获取msg结构

key 一个端口号或者由ftok获取

msgflg :

IPC_CREAT 不存在则创建,否则打开

IPC_EXCL 不存在新建,否则返回错误 

两个参数一起使用,那么.不存在则创建一个并打开,否则返回-1

向队列发数据/获取数据

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可

定义的通用结构,形态如下:

struct msgstru{

long mtype; //大大于0

char mtext[用户指定大大小小];

};

msgtyp:从消息队列内读取的消息形态。如果值为零,则表示消息队列中的所有消息都会被读取。

flag为0 时阻塞方式,IPC_NOWAIT非阻塞

设置消息属性

int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

IPC_STAT : 该命令用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指定的地址空间。

IPC_SET : 该命令用用来设置消息队列的属性,要设置的属性存储在buf中。

IPC_RMID : 从内核中删除 msqid 标识的消息队列。

ftok函数  

函数ftok把一个已存在的路径名和一个整数标识得转换成一个key_t值,称为IPC键:      

key_t ftok(const char *pathname, int proj_id);

该函数把从pathname导出的信息与id的低序8位组合成一个整数IPC键。

信号量

信号量的本质是数据操作锁,她本省不具有数据交换的功能,而是通过控制其他通信资源来实现进程间通信,他本身只是一种外部资源的标识.

在这个过程中,信号量负责是数据操作的互斥,同步等功能

当请求一个使用信号量来表示的资源时,进程需要先读取信号量的值来判断资源是否可用.

大于0,资源可以请求,等于0,无资源可用,进程进入睡眠状态直到资源可用.

当进程不再使用该资源时,信号量+1,对信号量的操作均为原子操作,

信号量的工作原理

P/V

P:如果sv的值大于0,给他减一,;如果值为0 ,挂起该进程

V:如果有其他进程因为等待该sv而挂起,就让他恢复运行,如果没有进程等待,那么sv+1

上一篇下一篇

猜你喜欢

热点阅读