Linux进程如何共享文件描述符
导读:在Linux中,进程可以通过多种方式共享文件描述符。以下是一些常见的方法: 1. fork( 系统调用 当一个进程调用 fork( 创建子进程时,子进程会继承父进程的所有文件描述符。这意味着子进程和父进程将共享相同的文件描述符表,指向相...
在Linux中,进程可以通过多种方式共享文件描述符。以下是一些常见的方法:
1. fork() 系统调用
当一个进程调用 fork() 创建子进程时,子进程会继承父进程的所有文件描述符。这意味着子进程和父进程将共享相同的文件描述符表,指向相同的文件表项。
#include <
stdio.h>
#include <
unistd.h>
int main() {
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
pid_t pid = fork();
if (pid == -1) {
perror("fork");
close(fd);
return 1;
}
else if (pid == 0) {
// 子进程
printf("Child process: fd = %d\n", fd);
close(fd);
// 子进程关闭文件描述符
}
else {
// 父进程
printf("Parent process: fd = %d\n", fd);
close(fd);
// 父进程关闭文件描述符
}
return 0;
}
2. dup() 和 dup2() 系统调用
dup() 和 dup2() 系统调用可以用于复制文件描述符。dup() 返回一个新的文件描述符,指向与现有文件描述符相同的文件表项。dup2() 可以将一个文件描述符重定向到另一个文件描述符。
#include <
stdio.h>
#include <
unistd.h>
#include <
fcntl.h>
int main() {
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
int fd2 = dup(fd);
if (fd2 == -1) {
perror("dup");
close(fd);
return 1;
}
printf("Original fd: %d\n", fd);
printf("Duplicated fd: %d\n", fd2);
close(fd);
// 关闭原始文件描述符
close(fd2);
// 关闭复制的文件描述符
return 0;
}
3. socketpair() 系统调用
socketpair() 系统调用可以创建一对相互连接的套接字描述符,这些套接字描述符可以在进程间共享。
#include <
stdio.h>
#include <
unistd.h>
#include <
sys/socket.h>
int main() {
int sockets[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
perror("socketpair");
return 1;
}
printf("Socket 1: %d\n", sockets[0]);
printf("Socket 2: %d\n", sockets[1]);
close(sockets[0]);
close(sockets[1]);
return 0;
}
4. pipe() 系统调用
pipe() 系统调用可以创建一个管道,管道的两个端点可以作为文件描述符在进程间共享。
#include <
stdio.h>
#include <
unistd.h>
int main() {
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
return 1;
}
printf("Read end of pipe: %d\n", pipefd[0]);
printf("Write end of pipe: %d\n", pipefd[1]);
close(pipefd[0]);
close(pipefd[1]);
return 0;
}
5. sendmsg() 和 recvmsg() 系统调用
sendmsg() 和 recvmsg() 系统调用可以用于在进程间传递文件描述符。
#include <
stdio.h>
#include <
stdlib.h>
#include <
string.h>
#include <
sys/socket.h>
#include <
unistd.h>
#include <
sys/uio.h>
int main() {
int sockets[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
perror("socketpair");
return 1;
}
char buf[] = "Hello, World!";
struct msghdr msg;
struct iovec iov;
char cmsgbuf[CMSG_SPACE(sizeof(int))];
struct cmsghdr *cmsg;
iov.iov_base = buf;
iov.iov_len = strlen(buf);
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &
iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
cmsg = CMSG_FIRSTHDR(&
msg);
cmsg->
cmsg_level = SOL_SOCKET;
cmsg->
cmsg_type = SCM_RIGHTS;
cmsg->
cmsg_len = CMSG_LEN(sizeof(int));
*(int *)CMSG_DATA(cmsg) = sockets[1];
if (sendmsg(sockets[0], &
msg, 0) == -1) {
perror("sendmsg");
close(sockets[0]);
close(sockets[1]);
return 1;
}
close(sockets[0]);
char recvbuf[1024];
iov.iov_base = recvbuf;
iov.iov_len = sizeof(recvbuf);
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &
iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
if (recvmsg(sockets[1], &
msg, 0) == -1) {
perror("recvmsg");
close(sockets[1]);
return 1;
}
printf("Received message: %s\n", recvbuf);
close(sockets[1]);
return 0;
}
这些方法可以帮助你在Linux进程间共享文件描述符。选择哪种方法取决于你的具体需求和应用场景。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: Linux进程如何共享文件描述符
本文地址: https://pptw.com/jishu/772905.html
