C ++中的时间线程

时间:2018-11-16 19:23:42

标签: c++ multithreading

如何将C ++程序分成两个时间流?

任务如下所示:每t秒向品种添加一个随机元素,而每n秒从品种中删除一个随机元素。 N和t是随机选择的数字。

我对递归函数有所了解,但实际上我不知道如何实现。

1 个答案:

答案 0 :(得分:0)

一种(非同步)方法

在C ++ 11和更高版本中,您可以使用std::threadstd::mutexstd::atomic做类似的事情

#include <atomic>
#include <mutex>
#include <thread>

void n_function(varietyType variety, int n);

std::mutex mtx;
std::atomic<int> time = 0;
int end = 0;      // This must be given a value greater than zero for anything to happen

int main() {
  int t;      // These must be assigned a value larger than zero
  int n;      // Additionally, they are type-agnostic - they don't have to be int,
              // if the rest of this example code is modified accordingly.

  std::thread n_thread(n_function, variety, n);

  int prev = time;
  while (time < end) {
    time += 1;
    if (time - prev >= t) {
      prev = time;
      mtx.lock();
      // add element
      mtx.unlock();
    }
  }
  n_thread.join();
}

n_function

void n_function(varietyType variety, int n) {
  int prev = time;
  while (time < end) {
    if (time - prev >= n) {
      prev = time;
      mtx.lock();
      // delete element
      mtx.unlock();
    }
  }
}

注意

  • 这将非常快速地工作(除静音之外),但是由于线程未锁步,因此容易丢失删除项(即使用n_h = 4执行1000个步骤可能只会执行241次删除而不是删除) (应该是250个)),尤其是如果元素删除的频率比添加元素的频率高。此外,添加或删除元素的速度也会产生影响-更快的添加/删除会增加未命中的可能性。

  • 如果您想将其与CPU时钟相关联,并建议tn秒以“ wall-clock”秒为单位反映 actual 时间,我建议而不是使用原子计数器来查看std::chrono

  • 对于更长的时间间隔,请根据需要使用std::atomic<unsigned long> time或什至std::atomic<unsigned long long> time

另一种(同步)方法

如果速度不如准确性重要(现实是,在大多数情况下,这两种方法的速度非常接近),则最好使用三个线程(两个子代,一个父代)来修改品种。即

#include <atomic>
#include <mutex>
#include <thread>

std::mutex mtx;

void n_function(varietyType variety, int n);
void t_function(varietyType variety, int t);

std::atomic<int> check = 0;
std::atomic<int> time = 0;
int end = 0;      // This must be given a value greater than zero for anything to happen

int main() {
  int t;        // Again these must be given a value greater than 0
  int n;
  std::thread n_thread(n_function, variety, n);
  std::thread t_thread(t_function, variety, t);

  while (time < end) {
    time += 1;
    check = 2;
    while (check != 0) {}    // blocking wait loop - use caution
  }
  n_thread.join();
  t_thread.join();
}

t_functionn_function

void t_function(varietyType variety, int t) {
    int prev = time;
    while (time < end) {
        if (time - prev >= t && check > 0) {
          prev = time;
          mtx.lock();
          // add element
          mtx.unlock();
        }
        check --;
    }
}

void n_function(varietyType variety, int n) {
    int prev = time;
    while (time < end) {
        if (time - prev >= n && check > 0) {
          prev = time;
          mtx.lock();
          // add element
          mtx.unlock();
        }
        check --;
    }
}

注意

  • 这两种方法都假设variety是共享内存,可以声明为指针或显式声明为共享内存。

  • 这两种方法都可能(并且可能会)比单线程方法效率更低,除非元素的添加/删除在计算上很昂贵(即,如果要删除的内容涉及大量计算,或者是否元素具有较大的内存占用)。

  • 诸如线程必须彼此等待之类的个人同步方法使我感到紧张,因为如果其中任何一个由于某种原因挂起,那么整个事情都会挂起-取决于应用程序,它可能比仅一个或两个更糟糕。一些线程挂起。

希望这会有所帮助。