多进程并发编程----进程间传递文件描述符基础~发送接收附属数据函数介绍

        如果fork进程之后,子进程如果想要传递描述给父进程一般使用socketpair函数。

此篇文章不介绍socketpair函数,二是介绍sendmsg和recvmsg函数,这两个函数隐藏的机构体有针对socket描述符的选项。

具体如下:

这两个函数为程序提供了一些其他的套接口I/O接口所不具备的高级特性。

从概念上说,sendmsg函数是所有写入函数的基础,而他是从属于套接口的。下面的列表以复杂增加的顺序列出了所有函数。在每一个层次上,同时列出了所增加的特性。
函数        增加的特性
write        最简单的套接口写入函数
send        增加了flags标记
sendto        增加了套接口地址与套接口长度参数
writev        没有标记与套接口地址,但是具有分散写入的能力
sendmsg        增加标记,套接口地址与长度,分散写入以及附属数据的能力


sendmsg函数

sendmsg函数原型如下:
int sendmsg(int s, const struct msghdr *msg, unsigned int flags);
函数参数描述如下:
要在其上发送消息的套接口s
信息头结构指针msg,这会控制函数调用的功能
可选的标记位参数flags。这与send或是sendto函数调用的标记参数相同。
函数的返回值为实际发送的字节数。否则,返回-1表明发生了错误,而errno表明错误原因。


recvmsg函数
recvmsg是与sendmsg函数相对的函数。这个函数原型如下:
int recvmsg(int s, struct msghdr *msg, unsigned int flags);
函数参数如下:
要在其上接收信息的套接口s
信息头结构指针msg,这会控制函数调用的操作。
可选标记位参数flags。这与recv或是recvfrom函数调用的标记参数相同。
这个函数的返回值为实际接收的字节数。否则,返回-1表明发生了错误,而errno表明错误原因。
理解struct msghdr
当我第一次看到他时,他看上去似乎是一个需要创建的巨大的结构。但是不要怕。其结构定义如下:
struct msghdr {
    void         *msg_name;
    socklen_t    msg_namelen;
    struct iovec *msg_iov;
    size_t       msg_iovlen;
    void         *msg_control;
    size_t       msg_controllen;
    int          msg_flags;
};
结构成员可以分为四组。他们是:
套接口地址成员msg_name与msg_namelen。
I/O向量引用msg_iov与msg_iovlen。
附属数据缓冲区成员msg_control与msg_controllen。
接收信息标记位msg_flags。
在我们将这个结构分为上面的几类以后,结构看起来就不那样巨大了。
成员msg_name与msg_namelen
这些成员只有当我们的套接口是一个数据报套接口时才需要。msg_name成员指向我们要发送或是接收信息的套接口地址。成员msg_namelen指明了这个套接口地址的长度。
当调用recvmsg时,msg_name会指向一个将要接收的地址的接收区域。当调用sendmsg时,这会指向一个数据报将要发送到的目的地址。
注意,msg_name定义为一个(void *)数据类型。我们并不需要将我们的套接口地址转换为(struct sockaddr *)。
成员msg_iov与msg_iovlen
这些成员指定了我们的I/O向量数组的位置以及他包含多少项。msg_iov成员指向一个struct iovec数组。我们将会回忆起I/O向量指向我们的缓冲区。成员msg_iov指明了在我们的I/O向量数组中有多少元素。
成员msg_control与msg_controllen
这些成员指向了我们附属数据缓冲区并且表明了缓冲区大小。msg_control指向附属数据缓冲区,而msg_controllen指明了缓冲区大小。
成员msg_flags
当使用recvmsg时,这个成员用于接收特定的标记位(他并不用于sendmsg)。在这个位置可以接收的标记位如下表所示:
标记位        描述
MSG_EOR        当接收到记录结尾时会设置这一位。这通常对于SOCK_SEQPACKET套接口类型十分有用。
MSG_TRUNC    这个标记位表明数据的结尾被截短,因为接收缓冲区太小不足以接收全部的数据。
MSG_CTRUNC    这个标记位表明某些控制数据(附属数据)被截短,因为缓冲区太小。
MSG_OOB        这个标记位表明接收了带外数据。
MSG_ERRQUEUE    这个标记位表明没有接收到数据,但是返回一个扩展错误。


我们可以man手册页中查看更多的信息。


附属数据结构与宏

recvmsg与sendmsg函数允许程序发送或是接收附属数据。然而,这些额外的信息受限于一定的格式规则。下一节将会介绍控制信息头与程序将会用来管理这些信息的宏。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux多进程编程是指在Linux操作系统下,使用多个进程同时执行任务的编程方式。 在Linux中,每个进程都是一个独立的执行环境,有自己独立的地址空和资源。多进程编程可以通过创建多个进程来同时执行不同的任务,从而提高程序的并发性和效率。 在Linux中,可以使用fork()系统调用创建一个新的进程。原有进程称为父进程,新创建的进程称为子进程,父进程和子进程具有相同的代码段和数据段,但拥有不同的进程ID。 通过fork()创建的进程在执行时,会复制父进程的所有资源,包括打开的文件、文件描述符等。子进程独立于父进程运行,并且可以通过exec()系列函数来加载新的程序,替代原有的代码段和数据段,实现不同的任务。 多进程编程可以通过父子进程的通信来实现数据交换。常用的通信方式包括管道、共享内存、信号和套接字等。父进程可以通过管道或共享内存将数据传递给子进程,子进程可以通过套接字与其他进程进行通信,实现进程数据共享和同步。 多进程编程也需要注意避免进程的竞争条件和死锁。可以使用进程同步机制,如互斥锁和信号量,来保证多个进程对共享资源的互斥访问和同步执行。 总而言之,Linux多进程编程是一种有效利用多核处理器和提高程序并发性的编程方式,可以通过创建多个进程来同时执行不同的任务,并通过不同的进程通信方式来实现数据交换和同步执行。 ### 回答2: Linux多进程编程是指在Linux操作系统上使用多个进程同时执行任务的编程方式。 Linux作为一个多用户、多任务的操作系统,支持多进程的并行执行。多进程编程可以充分利用操作系统提供的资源管理和调度机制,实现并发性和并行性。 在Linux中,一个程序可以通过创建新的进程来执行不同的任务。多进程编程可以通过调用系统调用fork()创建新的进程,从而将任务分配给不同的进程执行。同时,通过调用系统调用exec()可以在子进程中加载新的程序代码,实现任务的切换和执行。 多进程编程可以实现任务的分割和并行化处理,提高了程序的执行效率和响应速度。不同的进程可以通过进程通信(IPC)机制来进行数据的交换和协调,如管道、信号、共享内存等。 在多进程编程中,需要注意进程的创建和销毁、进程通信的机制、进程的同步与互斥等问题。合理使用多进程编程可以更好地利用多核处理器的计算能力和资源,提高程序的并发性和性能。 总之,Linux多进程编程是一种高效利用操作系统资源的编程方式,可以实现任务的并行处理,提高程序的执行效率和响应速度。 ### 回答3: Linux多进程编程是指在Linux操作系统上使用多个进程进行编程的一种方法。在Linux下,可以创建多个进程来同时执行不同的任务,扩展系统的处理能力,提高整体的效率和响应速度。 多进程编程的主要特点是可以实现并发执行,每个进程独立运行,相互之不会相互干扰。在Linux中,可以使用fork()系统调用来创建新的进程,子进程的运行和父进程是并行的。子进程可以继承父进程的资源,如打开的文件描述符、信号处理等,也可以通过exec()系列系统调用来加载新的程序,实现进程的替换。 在多进程编程中,进程可以通过进程通信(IPC)方式进行数据交换和同步。常用的IPC机制有管道、共享内存、消息队列和信号量等。这些机制可以让多个进程传递数据、共享资源,实现各个进程的协作和通信。 多进程编程还可以通过进程管理和调度来控制各个进程的执行顺序和优先级,提高系统的整体性能。Linux提供了丰富的进程管理工具和调度算法,可以根据实际需求进行调整和配置,以达到最佳的性能和资源利用率。 总之,Linux多进程编程是一种高效的编程模式,可以充分利用多核处理器的优势,实现并发执行和资源共享。它不仅可以提高系统的处理能力和响应速度,还可以提高系统的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值