c++ - 如何在不让用户等待的情况下管理多个线程?

标签 c++ multithreading

抱歉,如果措辞不当,我不确定如何在标题中准确描述我想要的内容。但基本上我的目标是让用户输入时间并让程序在时间过去时提醒他们。时间过去后,程序会寻找另一个时间,同时允许用户输入更多次。基本上,它看起来像这样:

void printTime(tm time) {
    //sleep until time
    cout << "it is " << time << endl;
    lookForNextTime();
}

void lookForNextTime() {
    //find earliest time
    printTime(time);
}

int main() {
    //create thread in lookForNextTime
    while(true) {
        //ask user to insert more times until they quit
    }
}

所以当用户插入更多次时,另一个线程正在等待打印出最早的预定时间。如果用户输入的新时间晚于当前预定时间,则应该没有问题。但是,如果他们输入的时间早于下一次,会发生什么情况?

这就是问题所在。假设最早的预定时间是一个月后。用户输入从现在起两周后的新时间。那么我们该怎么办?我想再做一个线程。但是随后用户想要输入下周的时间。然后是三天后的某个时间。然后是明天的某个时间。等等。

我是多线程的新手,但让所有这些新线程不受监管地创建肯定不是一个好主意,对吧?那么我们如何控制它呢?当需要删除线程时,我们需要使用 .join,对吗?有没有一种方法可以实现不需要用户等待时间过去,并且可以不间断地继续输入更多次的join?

最佳答案

欢迎来到 StackOverflow。我自己对 C++ 中的线程处理还很陌生,所以我不熟悉最好的库和技术,但我至少可以分享一些我所知道的基础知识,希望这能让你了解从那里去哪里.

如果我理解正确的话,我相信你的问题主要围绕着join(),所以我将从这里开始。

调用 join() 是您在继续之前等待线程加入的方式,但您不必在创建线程后立即执行此操作,否则将毫无意义。您可以让线程以自己的方式继续运行,并且在完成时结束,而无需主线程的任何进一步输入(请纠正我,我弄错了)。

join() 的重要之处在于,您在退出程序之前在所有线程上调用它以等待它们(或者以其他方式中止它们,当然是安全的)。否则,即使在 main() 返回后它们仍将继续运行,并且当它们尝试访问内存时会导致问题,因为它们不再附加到正在运行的进程。另一个潜在用途可能是让一些工作线程在计算中的某些检查点匹配,以便在获取下一个工作 block 之前共享结果。

希望对您有所帮助。不过,我还有一些想法,我想我会分享这些想法,以防您或 future 的读者不熟悉此示例中涉及的其他一些概念。


你没有说明你是否有一种方法来跟踪时间并在线程之间共享它们,所以我只是抛出一个快速提示:

在添加或弹出缓冲区之前锁定缓冲区。

这样做很重要,可以避免竞争条件,即一个线程可能试图弹出一些东西,而另一个线程正在添加并导致出现奇怪的问题,特别是如果你最终使用类似 set from the standard library 的东西排序并确保您在插入时只有任何给定元素的一个拷贝。

如果您不熟悉锁定机制,那么您可以找到在 C++ 中使用互斥锁和信号量的示例,或者搜索“锁定”或“同步对象”。您可以考虑来自 standard library 的不起眼的 Mutex。 .


就实际创建线程而言,我想到了一些事情。一种想法是使用线程池。有几个库可用于处理线程池,其中一个例子是 Apple 的开源 Grand Central Dispatch (通常称为 libdispatch)肯定可以在 Linux 上使用,但对于 Windows,您可能需要查找其他内容(不幸的是,我对 Windows 平台不太熟悉)。它们管理您正在使用和未使用的线程的生命周期,因此它们可能会有所帮助。同样,我自己对此有点陌生,我不能 100% 确定这对你来说是最好的,特别是因为你还有项目的其他部分需要解决,但它可能值得研究。

即使不使用线程池(假设你使用 pthreads),我认为你不必太担心自己启动一堆线程,只要你对其设置一些合理的限制(多少是合理的我我不确定,但如果你查看 macOS 中的事件监视器或 Windows 中的任务管理器或 Linux 中的 TOP,你会发现在任何给定时间,你机器上的许多程序可能会摇摆相当多的线程——现在我有 5090 个线程在运行和 327 个进程。每个进程大约有 15.5 个线程。有些进程比这高得多)。

希望其中的内容有所帮助。

关于c++ - 如何在不让用户等待的情况下管理多个线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54611333/

相关文章:

c++ - 如何使用 QCustomPlot 在 Qt 中绘制多条图形线

JavaFX TextArea 立即更新

java - 不使用 `synchronized` 关键字的线程安全代码?

c++ - 适用于调试但不适用于发布

c++ - 将 double 转换为 QString

c++ - 在 C++ 中存储和访问图 block 属性

c++ - 继承共享内存

c++ - 递归调用可变参数函数的链接器错误

java - 将死线程对象包装在新线程对象中以重新启动它

c++ - 在 Qt 中使用完成信号退出线程并进行 clean_up 的正确方法