【问题标题】:can pthread_join be unblockant?pthread_join 可以畅通无阻吗?
【发布时间】:2020-08-03 03:22:27
【问题描述】:

我有这样的功能:

void create_serv_and_init_client(client_t *cl, serv_t *serv)
{
    static int i = 0;
    pthread_t thread_serv;

    if (i == 0) {
        *serv = create_serv_socket();
        if (pthread_create(&thread_serv, NULL, waiting_connection, \
        (void *)serv) < 0) {
            perror("could not create thread");
            exit(1);
        }
        pthread_join(thread_serv, NULL);
        cl[0] = create_client(0);
        printf("OK\n");
        i++;
    }
}

waiting_connection函数:

void *waiting_connection(void *server)
{
    serv_t *serv = (serv_t *)server;

    serv->newSocket = accept(serv->sockfd, (struct sockaddr*)&serv->newAddr, \
    &serv->addr_size);
    if (serv->newSocket < 0) {
        exit(1);
    }
    if ((serv->childpid = fork()) == 0) {
        close(serv->sockfd);
        while (recv(serv->newSocket, serv->buffer, 1024, 0) != 0) {
            printf("Client: %s\n", serv->buffer);
            send(serv->newSocket, serv->buffer, strlen(serv->buffer), 0);
            bzero(serv->buffer, sizeof(serv->buffer));
        }
    }
}

如果我没有 pthread_join,我将永远不会收到客户端发送的 msg,但是,它会阻塞我的程序,直到收到消息,但我想畅通无阻地等待客户端消息,所以可以这样做一个畅通无阻的等待,用于接收客户端消息?

【问题讨论】:

  • 你的程序对我来说是模糊的,thread_serv 是客户端还是服务器(我投票支持服务器但是......)?您说的是 pthread_join(thread_serv, NULL); 还是此处不可见的其他 pthread_join ?您谈到“等待“客户消息”,看来您必须查看 select
  • 还有“如果我不使用 pthread_join,我将永远不会收到客户端发送的 msg”并询问“pthread_join 是否可以解除阻塞?”似乎很矛盾。但可能您的问题不在于连接,如果您通过 socket 交换消息,请再次查看 select
  • 如果我不 pthread_join,我将永远不会收到客户端发送的 msg 你的设计很糟糕。重新考虑你想如何做事。欢迎来到编程——你开始写东西,然后意识到你把它搞砸了,必须重新开始。如果您继续编程,这将不是您最后一次这样做。有两种类型的程序员:编写糟糕代码的程序员和说谎者。 ;-)
  • Thread_serv 是服务器,我说的是pthread_join(thread_serv, NULL); ,但我可以这样做,但我只是不明白为什么这实际上不起作用.. @bruno
  • 骗子?真的像吗? @AndrewHenle我必须使用pthread,因为这个函数循环并且我必须等待消息客户端,所以我不能只调用waiting connection,因为它只会阻塞后面的程序......

标签: c sockets tcp pthreads client-server


【解决方案1】:

因为这是一个游戏,所以第一个客户端连接游戏时服务器启动,如果我的程序总是等待别人输入别人玩,实际连接的玩家不能玩,所以这个需要如果需要,可以畅通无阻地异步。

因此,您希望每个客户端连接一个线程,并且始终能够接受新的客户端连接。听起来不错。

在这种情况下,从给定客户端接收到的消息的管理必须在相应的线程中完成,而不是在主线程中。主线程只管理客户端连接并启动新线程,它不必加入其他线程。

所以 accept 是在主线程中完成的,而不是在分离的线程中,当它为该客户端启动新线程时,它会在参数中提供带有新客户端的套接字,然后 pthread_detach 新线程。

if ((serv->childpid = fork()) == 0) {
   close(serv->sockfd);

所有这些都不存在,没有fork,你使用线程。


当然另一种方法是完全不使用线程,而是fork,反正初始进程和子进程之间的角色是不变的。

您的问题是您没有为每个人分配正确的角色。

【讨论】:

    猜你喜欢
    • 2010-09-09
    • 2015-08-24
    • 1970-01-01
    • 2015-06-02
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多