从另一个线程中取消阻塞线程

问题描述 投票:0回答:2

我正在寻找一种方法,能够同时从网络接收数据时向终端输入数据。

为此,我创建了一个新的线程dataCapturestd::thread),它将使用std::cin获取输入。主线是接收器。

当网络发送字符串“end”时,程序需要退出。

这是简化的代码:

void dataCapture()
    while (! quit) {
        std::string data;
        std::cout << "Enter data: ";
        std::cin >> data;
    }
}

bool quit=false;

int main() {
    // socket creation
    // connection to server
    const std::string quit_value = "end";


    std::thread datacapture_T(dataCapture);

    while (! quit) {
        char recep[1024];
        recv(sd, recep, sizeof(recep),0);
        if (recep == quit_value) {
            quit=true;
        }
    }
    datacapture_T.join();
    return 0;
}

这不起作用,因为在接收"end"后,maindatacapture_T.join()阻挡,因为dataCapturestd::cin电话中受阻。

是否有可能从主要解锁dataCapture线程?

如果不是可以强行杀死它?

ps:我没有为了简化而包含锁。

感谢帮助!

c++ multithreading pthreads
2个回答
0
投票

你可以用std::cin关闭ctrl-z

解决这个问题的另一种方法是进入你的dataCapture()并通过做一个quit_value检查那里的break

编辑:考虑使用原子以及尽可能明确地定义读取/写入并发线程。不要认为它增加了太多的复杂性


0
投票

在理论上和实践中都没有以编程方式杀死线程的干净方法。

以编程方式解除阻塞和关闭线程的标准方法是等待输入(任何类型)是使用select()pipe()

  • 创建一个管道()。
  • select()which创建一个包含输入文件描述符和read()以及pipe()的文件描述符集。
  • 不要在cin上进行阻塞读取,而是对select()进行阻止调用。
  • 如果select()告诉你有什么东西可以从pipe()读取,退出线程。您可以清除所有资源并完成所有处理,因为您在线程中检测到终止请求。这是关键。
  • 如果select()告诉你有什么东西要从cin读取,请阅读并处理它。
  • 来自任何其他线程,例如在main()的末尾: 每当你想终止线程时,在pipe()中写一个字节(值无关紧要)。 join()线程。

您认为这种方法听起来是随意而复杂的?它是!然而,这是常见的做法,您可以依赖它来工作,因为它被许多框架和程序使用。

还有一些不太有利的选择,例如轮询输入(非阻塞)和检查停止标志。也许最有用的替代方法是根本不使用任何其他线程来获取输入,并对所有I / O使用单线程事件驱动系统,并在其他线程中执行内部处理。

线程不是实现I / O并发的有用机制。线程对于创建CPU处理并发很有用。

© www.soinside.com 2019 - 2024. All rights reserved.