может ли pthread_join быть неблокирующим? - PullRequest
0 голосов
/ 20 апреля 2020

у меня есть такая функция:

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++;
    }
}

функция wait_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, я никогда не получу отправленное сообщение от клиента, но, тем не менее, он заблокирует мою программу до получения сообщения, но я хочу получить неблокирующее ожидание клиентского сообщения, так что можно сделать неблокирующее ожидание получения клиентского сообщения?

1 Ответ

0 голосов
/ 20 апреля 2020

, потому что это игра, поэтому сервер запускается, когда первый клиент подключен к игре, и, если моя программа всегда будет ждать ввода других игроков, остальные подключенные игроки не могут играть, поэтому должен быть неблокирующим, асинхронным, если хотите.

Таким образом, вы хотите, чтобы по одному потоку на каждое клиентское соединение и всегда можно было принять новое клиентское соединение. Это звучит правильно.

В этом случае управление сообщениями, полученными от данного клиента, должно осуществляться в соответствующем потоке, а не в основном потоке. Основной поток только управляет клиентскими подключениями и запускает новые потоки, ему не нужно присоединяться к другим потокам.

Таким образом, accept выполняется в главном потоке, а не в разделенных потоках, и это дает сокету аргумент нового клиента при запуске нового потока для этого клиента, затем pthread_detach новый поток.

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

всего этого не существует, fork нет, вы используете потоки.


Конечно, другой способ - вообще не использовать потоки, кроме fork , в любом случае роли между исходным процессом и дочерним процессом неизменны.

Ваш проблема в том, что вы не назначали нужные роли всем.

...