进程间资源共享: ===>
进程间通信:
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)