C pthread 不启动

C pthread doesn't start

我正在用 C 编写一个简单的报价服务器,运行正在 Linux 上编写。它应该从一个文本文件中随机选择一个引用,然后启动两个线程:

我的问题是,虽然连接线程工作正常,但另一个甚至没有启动。

为了确认这一点,我尝试在线程执行的函数的开头添加一个调试打印,另一个在它的 while 循环中并打印 none(这些已从显示的代码中删除在这里)。

我还添加了一些代码来检查从它的手册页复制的 pthread_create() return 值,但我不确定它是否真的有效,因为它没有检测到任何错误。

我已经决定先启动 "timer thread" 并且根本不启动连接线程,但它仍然没有被执行。下面是相关代码,你可以在 GitHub:

上找到完整的源代码
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <time.h>
#include <stdbool.h>
#include <pthread.h>
#include <errno.h>

#define handle_error_en(en, msg) \
               do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

pthread_mutex_t quoteLock=PTHREAD_MUTEX_INITIALIZER;
pthread_t checkForNewDayThread, connectionHandlerThread;

void * timer_thread_code(){ //The thread will act as a timer checking every hour if a day has passed
    while (true) {
        sleep(3600);
        if (a_day_has_passed()) {
            pthread_mutex_lock(&quoteLock);
            QOTD = read_random_quote_from_file(pathToQOTDfile);
            pthread_mutex_unlock(&quoteLock);
        }
    }
}

void * connection_thread_code(int port){    //Code for the thread to handle connections
    struct sockaddr_in address;
    int server_fd, new_socket, opt = 1, addrlen = sizeof(address);

    // Creating socket file descriptor
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // Forcefully attaching socket to the port 1717
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))==-1)
    {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( port );

    // Forcefully attaching socket to the port 1717
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0)
    {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    if (listen(server_fd, 100) < 0)
    {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    printf("Listening on port %i\n", port);

    while(1) {  //connection handler loop
        if ((new_socket = accept(server_fd, (struct sockaddr *) &address, (socklen_t *) &addrlen)) < 0) {
            perror("accept");
            exit(EXIT_FAILURE);
        }
        pthread_mutex_lock(&quoteLock);
        send(new_socket, QOTD, strlen(QOTD), 0);
        pthread_mutex_unlock(&quoteLock);
        close(new_socket);
    }
}

int main(int argc, char const *argv[])
{
    int thread1, thread2, join;
    thread1=pthread_create(&connectionHandlerThread, NULL, connection_thread_code(port), NULL);
    if(thread1!=0) handle_error_en(thread1, "pthread_create");
    thread2=pthread_create(&checkForNewDayThread, NULL, timer_thread_code(), NULL);
    if(thread2!=0) handle_error_en(thread2, "pthread_create");
    join=pthread_join(connectionHandlerThread, NULL);
    if(join!=0) handle_error_en(join, "pthread_join");
    return 0;
}

注意:我只放了一个 pthread_join() 因为两个线程都应该 运行 永远,所以为了防止 return 从 main 开始,只加入两个线程中的一个就足够了。

在此先感谢所有帮助过我的人

当您像在代码中那样调用 pthread_create 时:

thread1=pthread_create(&connectionHandlerThread, NULL, connection_thread_code(port), NULL);

您实际上首先在主线程上调用 connection_thread_code(port),并将该函数调用的 return 值作为参数传递给 pthread_create

那不是你想做的。您想要将函数指针作为参数传递给 pthread_create,以及要传递给它的参数:

int port = 1234; /* <-- make sure this is in scope for the duration of the thread ! */
thread1 = pthread_create(&connectionHandlerThread, NULL, connection_thread_code, &port);
/* ... */
pthread_join(connectionHandlerThread, NULL);

为此,您的线程函数应具有以下签名:

void* connection_thread_code(void* port_ptr);

然后像这样获取端口:

int port = *((int*) port_ptr);

阅读更多有关将 int 参数传递给线程函数的信息 here

与第二个线程类似(传递函数指针而不是调用函数,并更改签名)。