C ++如何杀死或“刷新”线程?

时间:2019-02-08 02:52:38

标签: c++ multithreading

因此,我们有两个函数“ waitForShortestTime”和“ addTime”。

import math
import random

while True:
    arcsin_all = []
    while True:
        a = round(random.uniform(-2*math.pi, 2*math.pi), 2)
        b = round(random.uniform(-2*math.pi, 2*math.pi), 2)
        c = round(random.uniform(-2*math.pi, 2*math.pi), 2)
        x = round(random.uniform(-2*math.pi, 2*math.pi), 2)
        if a == 0 or b == 0:
            print("Denominator(s) Zero")
            pass
        else:
            break
    print("A =",a,", B =",b,", C =",c,", X =",x)
    sin = round(a*math.sin(b*x+c), 2)
    print("Y =",sin)
    for n in range(-10, 10):
        arcsin = round((math.asin(sin/a)-c+2*(math.pi)*n)/b, 2)
        arcsin_all.append(arcsin)
    if x in arcsin_all:
        print("Solved")
    else:
        print("Not Solved")
    input("Again?")

因此该线程正在等待特定时间过去。这是一系列时间中最短的时间。但是在另一个线程上说,用户调用“ addTime”,这会增加该系列的另一个时间。添加的时间可能最终比“线程B”正在等待的时间还要短,所以我想杀死该线程并“刷新”它,以便它在等待之前再次检查最短的时间。

void waitForShortestTime(tm time)
{
   sleep_until(system_clock::from_time_t (timelocal(&time)));
   cout << "done" << endl;
}

但是我想知道如何先杀死当前线程。

2 个答案:

答案 0 :(得分:1)

您是否考虑过使用条件变量?参见https://en.cppreference.com/w/cpp/thread/condition_variable

与其杀死线程,不如向其发送信号以使其唤醒,然后采取适当的措施。

我强烈建议您购买并阅读 C ++并发操作https://www.manning.com/books/c-plus-plus-concurrency-in-action-second-edition)一书,因为它对使用标准C ++编写多线程代码提供了很多解释。

因此,每当您需要在任何现有事件之前添加一个要处理的事件时,都可以发出该线程停止的信号,等待其停止并启动另一个线程。

或者您也可以简单地为该新事件使用更短的计时器启动另一个线程,并结合最大等待时间,这是在必须添加事件之前和唤醒太多方法之间进行权衡的一个好选择。

例如,假设大多数工作在接下来的30分钟或更长时间内,而您在接下来的5分钟内很少有新工作。然后,您可以告诉线程等待5分钟,当线程唤醒时,它会检查是否应在接下来的5分钟结束之前安排任何作业,如果这样,则使用较小的等待时间。

或者如果要求的精度不高(例如,您需要在计划的一分钟或两分钟内检查),则只需始终等待最多该时间(一或两分钟),然后检查是否有事要做现在。

在实践中,也不必杀死线程。您将其唤醒,然后让线程检查是否有事情要做,如果没有,那么下次应该处理某个项目并将其用于等待时间。

该事件也可以用于退出应用程序。

有时,使用最大延迟可以帮助确保如果某个事件丢失了,数据将在一定时间内得到处理,从而使应用程序更全面。另外,您可以执行一些运行状况检查,例如,在很长的延迟后,您仍未处理以前的作业(例如,您的错误导致无限循环)。

答案 1 :(得分:1)

这将完成您需要做的事情。它当前需要fmt库,但是很容易更改。它使用条件变量来完成魔术:

#include <fmt/core.h>
#include <iostream>
#include <thread>
#include <queue>
#include <vector>
#include <condition_variable>
#include <chrono>
#include <utility>
#include <string>
#include <mutex>

using timed_msg_t = ::std::pair<::std::chrono::system_clock::time_point,
                                 ::std::string>;

class time_smaller
{
 public:
   bool operator ()(timed_msg_t const &a, timed_msg_t const &b)
   {
      return b.first < a.first;
   }
};

using timer_queue = ::std::priority_queue<timed_msg_t,
                                          ::std::vector<timed_msg_t>,
                                          time_smaller>;

using ::std::mutex;
using ::std::condition_variable;
using ::std::thread;
using ::std::unique_lock;

static auto const start = ::std::chrono::system_clock::now();

void timer_queue_thread(mutex &queue_mutex,
                        condition_variable &queue_condition,
                        timer_queue &q)
{
   unique_lock<mutex> qlock(queue_mutex);
   while (!q.empty()) {
      auto now = ::std::chrono::system_clock::now();
      auto const &top = q.top();
      if (top.first <= now) {
         double milliseconds_from_start = (now - start) / ::std::chrono::milliseconds(1);
         ::fmt::print("At time: {}ms - \"{}\"\n", milliseconds_from_start, top.second);
         q.pop();
      } else {
         queue_condition.wait_until(qlock, top.first);
      }
   }
}

int main()
{
   timer_queue tq;
   mutex queue_mutex;
   condition_variable queue_condition;
   {
      unique_lock<mutex> qlock(queue_mutex);
      tq.emplace(start + 60 * ::std::chrono::seconds(1), "Starting event.");
   }
   ::std::thread timer_processing{timer_queue_thread, ::std::ref(queue_mutex), ::std::ref(queue_condition), ::std::ref(tq)};
   while (true) {
      int seconds;
      ::std::string msg;
      ::std::cout << "Enter a time and message:\n";
      ::std::cin >> seconds;
      getline(::std::cin, msg);
      {
         unique_lock<mutex> qlock(queue_mutex);
         auto const qtime = ::std::chrono::system_clock::now() + seconds * ::std::chrono::seconds(1);
         tq.emplace(qtime, msg);
         queue_condition.notify_one();
      }
   }
   return 0;
}