您的位置:首页 > 运维架构 > Linux

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

2014-10-21 20:12 543 查看
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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: