如何将C ++程序分成两个时间流?
任务如下所示:每t秒向品种添加一个随机元素,而每n秒从品种中删除一个随机元素。 N和t是随机选择的数字。
我对递归函数有所了解,但实际上我不知道如何实现。
答案 0 :(得分:0)
在C ++ 11和更高版本中,您可以使用std::thread
,std::mutex
和std::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时钟相关联,并建议t
和n
秒以“ 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_function
和n_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
是共享内存,可以声明为指针或显式声明为共享内存。
这两种方法都可能(并且可能会)比单线程方法效率更低,除非元素的添加/删除在计算上很昂贵(即,如果要删除的内容涉及大量计算,或者是否元素具有较大的内存占用)。
诸如线程必须彼此等待之类的个人同步方法使我感到紧张,因为如果其中任何一个由于某种原因挂起,那么整个事情都会挂起-取决于应用程序,它可能比仅一个或两个更糟糕。一些线程挂起。
希望这会有所帮助。