首页主机资讯Linux进程如何共享文件描述符

Linux进程如何共享文件描述符

时间2025-12-16 16:00:04发布访客分类主机资讯浏览740
导读:在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
Linux进程如何进行资源限制 Linux进程如何优化启动速度

游客 回复需填写必要信息