您现在的位置是:主页 > news > 浙江网站建设的释义/搜索引擎调词软件
浙江网站建设的释义/搜索引擎调词软件
admin2025/5/25 18:52:01【news】
简介浙江网站建设的释义,搜索引擎调词软件,网站什么时候做负载均衡,做哪些网站比较好进程间的通信类型 进程间的通信类型有如下六种: ① 管道(pipe)和有名管道(FIFO)。 ② 信号(signal)。 ③ 共享内存。 ④ 消息队列。 ⑤ 信号量。 ⑥ 套接字(socket࿰…
进程间的通信类型
进程间的通信类型有如下六种:
① 管道(pipe)和有名管道(FIFO)。
② 信号(signal)。
③ 共享内存。
④ 消息队列。
⑤ 信号量。
⑥ 套接字(socket)。
进程间通信目的
进程间通信目的有如下五种:
① 数据传输:一个进程需要将它的数据发送给另一个进程。
② 共享数据:多个进程想要共享数据,一个进程对共享数据进行修改后,别的进程可以立刻看到。
③ 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
④ 资源共享:多个进程之间共享同样的资源。为了做到这一点,需要内核提供锁和同步机制。
⑤ 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。
管道pipe
管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
从原理上,管道利用fork机制建立,从而让两个进程可以连接到同一个PIPE上。
在 Linux 中,管道的实现并没有使用专门的数据结构,而是借助了文件系统的file结构和VFS的索引节点inode。通过将两个 file 结构指向同一个临时的 VFS 索引节点,而这个 VFS 索引节点又指向一个物理页面而实现的。
有两个 file 数据结构,但它们定义文件操作例程地址是不同的,其中一个是向管道中写入数据的例程地址,而另一个是从管道中读出数据的例程地址。这样,用户程序的系统调用仍然是通常的文件操作,而内核却利用这种抽象机制实现了管道这一特殊操作。
Linux函数原型
#include <unistd.h>
int pipe(int filedes[2]);
filedes[0]用于读出数据,读取时必须关闭写入端,即close(filedes[1]);
filedes[1]用于写入数据,写入时必须关闭读取端,即close(filedes[0])。
int main(void)
{int n;int fd[2];pid_t pid;char line[MAXLINE];if(pipe(fd) 0){ /* 先建立管道得到一对文件描述符 */exit(0);}if((pid = fork()) 0) /* 父进程把文件描述符复制给子进程 */exit(1);else if(pid > 0){ /* 父进程写 */close(fd[0]); /* 关闭读描述符 */write(fd[1], "\nhello world\n", 14);}else{ /* 子进程读 */close(fd[1]); /* 关闭写端 */n = read(fd[0], line, MAXLINE);write(STDOUT_FILENO, line, n);}exit(0);
}
命名管道FIFO
由于基于fork机制,所以管道只能用于父进程和子进程之间,或者拥有相同祖先的两个子进程之间 (有亲缘关系的进程之间)。为了解决这一问题,Linux提供了FIFO方式连接进程。FIFO又叫做命名管道(named PIPE)。
FIFO (First in, First out)为一种特殊的文件类型,它在文件系统中有对应的路径。当一个进程以读®的方式打开该文件,而另一个进程以写(w)的方式打开该文件,那么内核就会在这两个进程之间建立管道,所以FIFO实际上也由内核管理,不与硬盘打交道。之所以叫FIFO,是因为管道本质上是一个先进先出的队列数据结构,最早放入的数据被最先读出来,从而保证信息交流的顺序。FIFO只是借用了文件系统来为管道命名。写模式的进程向FIFO文件中写入,而读模式的进程从FIFO文件中读出。当删除FIFO文件时,管道连接也随之消失。FIFO的好处在于我们可以通过文件的路径来识别管道,从而让没有亲缘关系的进程之间建立连接。
函数原型:
#include <sys/types.h>#include <sys/stat.h>int mkfifo(const char *filename, mode_t mode);int mknode(const char *filename, mode_t mode | S_IFIFO, (dev_t) 0 );#define MONITOR_FIFO_NAME "/tmp/monitor_fifo"unlink(MONITOR_FIFO_NAME);mkfifo(MONITOR_FIFO_NAME, S_IRUSR | S_IWUSR)fd_fifo = open(MONITOR_FIFO_NAME, O_RDONLY | O_NONBLOCK); len = read(fd_fifo, &msg, sizeof(monitor_msg));s_fd_fifo = open(MONITOR_FIFO_NAME, O_WRONLY | O_NONBLOCK); len = write(s_fd_fifo, &msg, sizeof(monitor_msg));
其中pathname是被创建的文件名称,mode表示将在该文件上设置的权限位和将被创建的文件类型(在此情况下为S_IFIFO),dev是当创建设备特殊文件时使用的一个值。因此,对于先进先出文件它的值为0
共享内存
函数原型
fd = shm_open(name, flag, 0666);
ret = ftruncate(fd, size);
ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
memcpy(ptr, data, size);//write
memcpy(data, ptr, size);//read
//release
ret = munmap(ptr, size);
ret = shm_unlink(name);
消息队列
函数原型
msgId = msgget((key_t)((msgMaxLen << 16)|(msgMaxSize << 8)),0666|IPC_CREAT);iRet = msgsnd(msgId,(void *)msg,msgSize,IPC_NOWAIT);iRet = msgrcv(msgId,msgBuf,msgSize,0, IPC_NOWAIT|MSG_NOERROR);iRet = msgctl(msgId,IPC_RMID,NULL);
消息队列与命名管道的比较
消息队列跟命名管道有不少的相同之处,通过与命名管道一样,消息队列进行通信的进程可以是不相关的进程,同时它们都是通过发送和接收的方式来传递数据的。在命名管道中,发送数据用write(),接收数据用read(),则在消息队列中,发送数据用msgsnd(),接收数据用msgrcv()。而且它们对每个数据都有一个最大长度的限制。
与命名管道相比,消息队列的优势在于:
1、消息队列也可以独立于发送和接收进程而存在,从而消除了在同步命名管道的打开和关闭时可能产生的困难。
2、同时通过发送消息还可以避免命名管道的同步和阻塞问题,不需要由进程自己来提供同步方法。
3、接收程序可以通过消息类型有选择地接收数据,而不是像命名管道中那样,只能默认地接收。