【问题标题】:C++ socket read() inside child thread giving SIGABRT子线程内的 C++ 套接字 read() 给出 SIGABRT
【发布时间】:2021-08-29 21:09:07
【问题描述】:

我正在为每个客户端连接在单独的std::thread 中处理到套接字的传入连接。因此,当尝试从套接字执行read() 时,程序会崩溃。

std::thread in_conn_th(handle_new_connection, in_socket);  // <-- creating a new thread and passing the handle_new_connection function into the thread with the socket descriptor param

这里是handle_new_connection()的描述

waiterr::operation_codes waiterr::Waiter::handle_new_connection(int incoming_socket) {
    std::cout << "Here comes " << incoming_socket << "\n";

    char buffer[30000] = {0};

    int val_read = read(incoming_socket, buffer, 30000);  // <-- Error

    std::cout << "Here comes 2\n";

    std::cout << buffer << std::endl << std::endl;
    write(incoming_socket, "Some response", 13);

    std::cout << "* Msg sent *\n";
    close(incoming_socket);

    return operation_codes(OK);
}

错误

shantanu@Shantanus-MacBook-Pro webserver % ./test1.o                                                   
* Waiting for new connection *
libc++abi: terminating
Here comes 4
zsh: abort      ./test1.o

如果我只是调用handle_new_connection() 而不产生新线程,则操作成功并在客户端显示响应。

所以我很确定它是关于一些我不知道的线程的事情。

环境 - 苹果 M1 硅;在 ARM 上本机运行 g++。

编辑 handle_new_connection()的函数定义

static enum operation_codes handle_new_connection(int incoming_socket);

【问题讨论】:

  • read() 调用失败的唯一方法是如果incoming_socket 已损坏,则给出显示的代码。 waiterr::Waiter 是命名空间还是类?如果是后者,那么handle_new_connection() 是静态的还是非静态的?这些对int incoming_socket 在调用堆栈上传递给handle_new_connection() 的方式和位置产生了很大的影响。请提供minimal reproducible example
  • waiterr::Waiter 是一个类。 handle_new_connection 是静态的
  • 如果in_socketincoming_socket 具有相同的值,那么显示的read() 就不可能失败。但是,std::cout &lt;&lt; buffer 可能会失败,如果read() 返回恰好 30000 字节,那么buffer 不会以空值终止。改用cout.write(buffer, val_read)(在验证val_read 不是&lt;= 0 之后)
  • 您的输出中的“libc++abi: terminating”是什么?您是否在线程有机会使用套接字之前终止您的应用程序?
  • 我无法看到打印的第二个 cout 语句。这样可以确保在此之上发生一些事情

标签: c++ multithreading sockets pthreads


【解决方案1】:

我用pthread_t 代替std::thread,效果很好。

而不是

std::thread in_conn_th(handle_new_connection, in_socket);

我用过

pthread_t in_conn_th;
pthread_create(&in_conn_th, NULL, handle_new_connection, (void*)(&in_socket));

并更改函数定义以接收void *

不要忘记包含pthread.h 标头。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多