从pthread C调用时,read()不起作用



我目前正在编写一个C服务器,目标是使用pthreads来处理客户端连接,在引入pthreads之前,一切都很好。我在pthread上启动了一个客户端,它被创建并运行良好;但是,它将不再从客户端的文件描述符中"read()"。

我已经想了大概两个星期了。我已经包含了服务器代码(包括和不包括pthreads.)和客户端处理程序代码的代码片段。

这是我的主服务器循环(pthread):

/*Sets up and runs the server. (MAX 10 CLIENTS)*/
void publicServer(void)
{
    //Server locals
    int serverSocket_fd;
    int clientSocket_fd;
    socklen_t serverLength;
    socklen_t clientLength;
    struct sockaddr_in serverAddress;
    struct sockaddr_in clientAddress;
    //Threading locals
    pthread_t threadPool[20];   //Pool of threads, used in a FIFO fashion.
    int threadPointer = 0;      //Points to the location of the next available thread.
    //Clear old sockets
    puts("Unlinking server socket");
    unlink("server_socket");
    //Setup server socket
    printf("Setting server socket properties..n");
    serverSocket_fd                 = socket(AF_INET, SOCK_STREAM, 0);
    serverAddress.sin_family        = AF_INET;
    serverAddress.sin_addr.s_addr   = htonl(INADDR_ANY);
    serverAddress.sin_port          = htons(5000);
    serverLength = sizeof(serverAddress);
    //Bind the socket
    printf("Binding socketn");
    bind(serverSocket_fd, (struct sockaddr*)&serverAddress, serverLength);
    //Create listener
    listen(serverSocket_fd, 20);
    //Main server loop
    printf("Entering main loopn");
    while (1)
    {
        clientLength = sizeof(clientAddress);
        //Accept connection
        printf("Blocking for connectionn");
        clientSocket_fd = accept(serverSocket_fd, (struct sockaddr*)&clientAddress, &clientLength);
        //Handle Client
        pthread_create(&threadPool[0], NULL, clientHandler, clientSocket_fd);
        //Increment thread pointer
        threadPointer++;
        if (threadPointer == 20)
        {
            threadPointer = 0;
        }
        //End client
        close(clientSocket_fd);
    }
}

以下是没有pthreads的服务器代码(工作正常。):

/*Sets up and runs the server. (MAX 10 CLIENTS)*/
void publicServer(void)
{
    //Server locals
    int serverSocket_fd;
    int clientSocket_fd;
    socklen_t serverLength;
    socklen_t clientLength;
    struct sockaddr_in serverAddress;
    struct sockaddr_in clientAddress;
    //Clear old sockets
    puts("Unlinking server socket");
    unlink("server_socket");
    //Setup server socket
    printf("Setting server socket properties..n");
    serverSocket_fd                 = socket(AF_INET, SOCK_STREAM, 0);
    serverAddress.sin_family        = AF_INET;
    serverAddress.sin_addr.s_addr   = htonl(INADDR_ANY);
    serverAddress.sin_port          = htons(5000);
    serverLength = sizeof(serverAddress);
    //Bind the socket
    printf("Binding socketn");
    bind(serverSocket_fd, (struct sockaddr*)&serverAddress, serverLength);
    //Create listener
    listen(serverSocket_fd, 20);
    //Main server loop
    printf("Entering main loopn");
    while (1)
    {
        clientLength = sizeof(clientAddress);
        //Accept connection
        printf("Blocking for connectionn");
        clientSocket_fd = accept(serverSocket_fd, (struct sockaddr*)&clientAddress, &clientLength);
        //Handle Client
        clientHandler(clientSocket_fd);
        //End client
        close(clientSocket_fd);
    }
}

以下是客户端处理程序代码:

/*
 * Handles the client's request.
 * <int : client_fd> Client's file descriptor.
 */
void *clientHandler(int client_fd)
{
    char request = ' ';
    puts("Waiting for request");
    read(client_fd, &request, 1);
    //Determine what to do for user
    if (request == '1')                 //Output current temp and pressure
    {
        outputCurrentTemperaturePressure(client_fd);
    }
    else if (request == '2')            //Begin regular sampling of temp and pressure
    {
        startSampling();
    }
    else if (request == '3')            //Stop regular sampling of temp and pressure
    {
        stopSampling();
    }
    else if (request == '4')            //Clear the EEPROM
    {
        eraseEEPROM();
    }
    else if (request == '5')            //Retrieve all stored temperature and pressure values
    {
        outputSavedTempPressValues(client_fd);
    }
    else if (request == '6')            //Retrieve a certain number of temperature and pressure values
    {
        outputLastNTempPressValues(client_fd);
    }
    else if (request == '7')            //Output current noise level
    {
        outputCurrentNoiseLevel(client_fd);
    }
    close(client_fd);
    pthread_exit(1);
}

当我尝试从客户端读取时,问题出现在clientHandler方法中的第6行。当在pthread上运行时,它一直读取0。但是,当在没有pthreads的情况下运行时,它会读取正确的值。我希望有人能帮上忙,因为这真的让我很困惑

提前感谢,Andy

在我看来,pthread入口点必须有一个void*参数。您定义clientHandler的方式似乎是错误的。阅读以下内容:http://timmurphy.org/2010/05/04/pthreads-in-c-a-minimal-working-example/.

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                      void *(*start_routine) (void *), void *arg);

pthread_create(&threadPool[0], NULL, clientHandler, (void*)&clientSocket_fd);
void *clientHandler(void *args) {
int client_fd = *((int*) args);

只关闭线程中的客户端socket_fd,但不关闭主函数

while (1)
{
    clientLength = sizeof(clientAddress);
    //Accept connection
    printf("Blocking for connectionn");
    clientSocket_fd = accept(serverSocket_fd, (struct sockaddr*)&clientAddress, &clientLength);
    //Handle Client
    pthread_create(&threadPool[0], NULL, clientHandler, clientSocket_fd);
    //Increment thread pointer
    threadPointer++;
    if (threadPointer == 20)
    {
        threadPointer = 0;
    }
    //End client
    /* remove close(clientSocket_fd) from here */
}

当您在while中运行新线程时,循环仍然关闭cliend文件描述符,这就是read()不工作的原因

最新更新