linux 系统编程-学习笔记10--进程间通信--管道/FIFO/消息队列/

来源:互联网 发布:vr分屏软件 编辑:程序博客网 时间:2024/04/29 06:32
linux:
进程间资源共享: ===>
进程间通信:
1.管道
1)无名管道
:同一台主机:在具有亲缘关系的进程间通信(半双工通信:一端要么读要么写,不能同时读写)
亲缘关系:1.父、子进程
 2.具有同一个父进程的两个子进程


调用pipe在内核中建立一个无名管道,会有固定的读端和写端
int pipe(int pipefd[2]);

int pip[2];
pipe(pip)==>调用pipe在内核中建立一个无名管道pip,会有固定的读端pip[0]和写端pip[1]

return : 
On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

管道:1.会阻塞
      2.管道中的数据,如果被读走,就没了(水管)

====================================================================================================
FILE *popen(const char *command, const char *type);
调用popen会自动创建一个管道和终端相连,之后该管道根据type进行和终端交互
commond: shell命令
type   : r / w

返回流指针文件

int pclose(FILE *stream);

_______________________________________________

/*******************************
int fileno(FILE *stream);
流指针转换为文件描述符
*******************************/


FILE *fdopen(int fd, const char *mode);
把文件描述符转换为流指针
fd :文件描述符
mode : r w w+ ......

struc {
int fd; //文件描述符
}FILE;
====================================================================================================

2)有名管道:半双工通信,同一台主机,任意的进程间通信

int mkfifo(const char *pathname, mode_t mode);
功能:建立一个有名管道
pathname  : 文件名
mode      : 0666/0777


RETURN VALUE
On success mkfifo() returns 0.  In the case of an
error, -1 is returned (in which case, errno is set
appropriately).

====================================================================================================
2.消息队列
1.消息队列类似于链表,同一台主机上不同的进程通过一个相同的关键字key,获取/创建一个相同的消息队列
通过消息队列进行进程间通信


消息队列的操作:
1.创建消息队列(返回一个消息队列ID)
int msgget(key_t key, int msgflg);
功能:创建一个消息队列,并返回消息队列ID
key: 关键字,是不同的进程间进行通信的纽带(关键字由ftok获取)
     IPC_PRIVATE  : 表示每次都能够获取到惟一的消息队列ID
     
magflg: 
IPC_CREAT :创建一个消息队列,如果存在直接返回该消息队列的ID
IPC_EXCL  :如果该消息队列存在,则返回错误errno

_______________________________________________________________
key_t ftok(const char *pathname, int proj_id);
功能:通过文件名pathname的inode节点号和整数proj_id共同组合二成的关键字
pathname  : 文件名(作用:提供文件inode节点号)
proj_id   : 非零的正整数

返回值:
成功=> key 失
败=>-1 
_________________________________________________________________


2.发送消息


int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:给消息队列发送消息


msqid : 消息队列ID(有msgget返回)
msgp  : 一个消息包(自己定义结构体)
struct msgbuf {
long mtype;       /* message type, must be > 0 */
char mtext[1];    /* message data */
};

msgsz : struct msgbuf (消息包)的大小
msgflg: 
IPC_NOWAIT:即使消息没有发送完成,函数也立即返回[移植性不好]
0 :一直发送,直到消息发送完成[常用方式]


RETURN VALUE
成功:返回0,
失败:返回-1
--------------------------------------------------------------------------
3.消息队列的接收
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
功能:从消息队列接收消息
msqid   : 消息队列ID(有msgget返回)
msgp    : 一个消息包(自己定义结构体)
struct msgbuf {
long mtype;       /* message type, must be > 0 */
char mtext[1];    /* message data */
};


msgsz   : struct msgbuf (消息包)的大小==>一次最多能接受到的大小


msgtype :(注意) 
0: 表示接收到消息队列中第一个消息
       >0: 表示接收类型为msgtype类型的消息


msgflg  : 
IPC_NOWAIT: 如果没由消息,则该进程立即返回
0 : 如果没有消息,一直等待(阻塞)


RETURN VALUE
成功:返回实际接收到的字节数

失败:返回-1

int semctl(int semid, int semnum, int cmd, ...);
semid : 信号量semid,由semget返回
semnum: 信号量的编号[信号量编号从0开始==>0,1,2,3........]
cmd   : SETVAL : 对信号量初始化
IPC_RMID : 删除信号量


RETURN VALUE
       On failure semctl() returns -1 with errno indicating the error.
-------------------------------------------------------------------------------------


3.p/v操作
int semop(int semid, struct sembuf *sops, unsigned nsops);
semid : 信号量semid,由semget返回


struct sembuf 结构体成员:
__________________________________________________________
unsigned short sem_num;  /* 信号量编号{0,1,2,3......}*/
short          sem_op;   /* 0:等待 1:v操作(释放) -1:p操作(通过).*/
short          sem_flg;  /* 一般默认为0 */
__________________________________________________________


nsops : 信号量的个数(恒大于等于1)


0 0
原创粉丝点击