【问题标题】:Why write() terminate my thread?为什么 write() 终止我的线程?
【发布时间】:2017-12-23 20:01:14
【问题描述】:

我用pthread_create()创建了一个线程来执行一个函数,在函数内部有一个write()函数通过套接字描述符发送数据。如果write()函数发送数据失败(因为socket连接丢失),我的线程就终止了。

write() 失败时我可以保留一个线程吗?

这是我的代码:

   void broadcastMsg(char *msg) {
        int i=0;
        while(1) {
            ...
            ...
            // My thread terminated from here
            if(write(client_database.sock_desc[i], msg, strlen(msg)) < 0) {
                client_database.sock_desc[i] = -3;
                i++;
                continue;
            }

            i++;
        }
    }

    /* Start thread from this function */
    void *cliListener(void *argvp) {
        int read_desc;
        char buf[MAX_TRANSFER_BUF];
        int cli_sock_desc_id = atoi(argvp);

        while(1) {
            memset(buf, 0, MAX_TRANSFER_BUF);
            read_desc = read(client_database.sock_desc[cli_sock_desc_id], buf, MAX_TRANSFER_BUF);

            ...
            ...

            broadcastMsg(buf);
        }
    }

    int main(void) {
        ...
        ...
        pthread_t tid_1;
        pthread_create(&tid_1, NULL, cliListener, cli_listener_arg);
        ...
        ...
    }

【问题讨论】:

  • 是的,您可以在写入失败后保留线程。多说,比如为什么线程终止了,就需要看代码了。请提供一个最小但完整的示例,但仍然存在相同的问题。
  • this previous question 有用吗?
  • 没有一个简单的例子我们帮不了你
  • 您的帖子正下方有一个按钮edit(它有点小而且灰色,但它就在那里)。您也可以单击此评论中的链接 :) 确保创建 minimal reproducible example;另请阅读How do I ask a good question?。您可能希望至少浏览一次tour,因为它涵盖了非常基础的内容。

标签: c multithreading sockets


【解决方案1】:

如果您尝试写入管道或套接字描述符的另一端已关闭(因此没有人会读取它),系统将向您的进程发送 SIGPIPE 信号,默认情况下会杀死进程1。您可以通过忽略 SIGPIPE 来避免这种命运,通常在 main 函数的早期:

signal(SIGPIPE, SIG_IGN);

一旦你这样做了,写入将不再杀死你的线程或进程;相反,它将返回一个错误 (-1),并将 errno 设置为 EPIPE。您需要确保您始终检查写入调用的返回值,并在出现错误时执行适当的操作,否则您的程序可能会在后台运行在你认为它已经停止之后......


1取决于你如何设置它可能只杀死线程而不是整个过程,但为了一般安全和卫生,它应该杀死整个进程

【讨论】:

  • 我看到我的代码几个小时,这可以通过添加 signal(SIGPIPE, SIG_IGN);在 main() 上。感谢这个解决方案,新手很难:D
  • 如果您忽略 SIGPIPE,我想强调始终检查 write 返回值。在您认为您已经杀死它们之后,很容易让程序挂起,否则会占用资源。请注意,这包括在后台使用write 的所有库函数(例如printf)。
猜你喜欢
  • 1970-01-01
  • 2019-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多