MST
星途 面试题库

面试题:C++ 多进程网络编程中共享资源的处理

在 C++ 进行网络编程并结合多进程的场景下,假设多个进程需要访问同一个网络套接字资源,可能会遇到什么问题?如何使用 C++ 中的机制(如互斥锁、信号量等)来解决这些问题,请简述思路并给出简单示例代码。
17.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

可能遇到的问题

  1. 资源竞争:多个进程同时访问和操作网络套接字,可能导致数据混乱、套接字状态不一致等问题。例如,一个进程正在发送数据时,另一个进程同时尝试读取或发送,可能造成数据损坏。
  2. 数据不一致:不同进程对套接字的读写操作可能相互干扰,导致数据的不完整性或错误解读。

解决思路

  1. 使用互斥锁(Mutex):互斥锁用于保证在同一时间只有一个进程能够访问网络套接字。当一个进程获取到互斥锁时,其他进程必须等待,直到该进程释放互斥锁。
  2. 使用信号量(Semaphore):信号量可以控制同时访问网络套接字的进程数量。可以设置信号量的初始值为1,这样就类似于互斥锁的效果;也可以设置大于1的值,允许一定数量的进程同时访问。

示例代码(使用互斥锁)

#include <iostream>
#include <mutex>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>

std::mutex socketMutex;

void processTask(int socketFd) {
    socketMutex.lock();
    // 操作网络套接字
    const char* message = "Hello, Server!";
    send(socketFd, message, strlen(message), 0);
    char buffer[1024];
    int bytesRead = recv(socketFd, buffer, sizeof(buffer), 0);
    buffer[bytesRead] = '\0';
    std::cout << "Received from server: " << buffer << std::endl;
    socketMutex.unlock();
}

int main() {
    int socketFd = socket(AF_INET, SOCK_STREAM, 0);
    if (socketFd == -1) {
        perror("Socket creation failed");
        return 1;
    }

    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8080);
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(socketFd, (sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Connect failed");
        close(socketFd);
        return 1;
    }

    pid_t pid = fork();
    if (pid == -1) {
        perror("Fork failed");
        close(socketFd);
        return 1;
    } else if (pid == 0) {
        // 子进程
        processTask(socketFd);
        close(socketFd);
        _exit(0);
    } else {
        // 父进程
        processTask(socketFd);
        wait(nullptr);
        close(socketFd);
    }

    return 0;
}

示例代码(使用信号量)

#include <iostream>
#include <semaphore.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>

sem_t socketSemaphore;

void processTask(int socketFd) {
    sem_wait(&socketSemaphore);
    // 操作网络套接字
    const char* message = "Hello, Server!";
    send(socketFd, message, strlen(message), 0);
    char buffer[1024];
    int bytesRead = recv(socketFd, buffer, sizeof(buffer), 0);
    buffer[bytesRead] = '\0';
    std::cout << "Received from server: " << buffer << std::endl;
    sem_post(&socketSemaphore);
}

int main() {
    sem_init(&socketSemaphore, 0, 1);

    int socketFd = socket(AF_INET, SOCK_STREAM, 0);
    if (socketFd == -1) {
        perror("Socket creation failed");
        sem_destroy(&socketSemaphore);
        return 1;
    }

    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8080);
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(socketFd, (sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Connect failed");
        close(socketFd);
        sem_destroy(&socketSemaphore);
        return 1;
    }

    pid_t pid = fork();
    if (pid == -1) {
        perror("Fork failed");
        close(socketFd);
        sem_destroy(&socketSemaphore);
        return 1;
    } else if (pid == 0) {
        // 子进程
        processTask(socketFd);
        close(socketFd);
        _exit(0);
    } else {
        // 父进程
        processTask(socketFd);
        wait(nullptr);
        close(socketFd);
    }

    sem_destroy(&socketSemaphore);
    return 0;
}