Как я могу разделить программу на C++ на 2 временных потока?
Задача выглядит так: случайный элемент добавляется в разнообразие каждые t секунд, а случайный элемент удаляется из множества каждые n секунд. N и t - произвольно выбранные числа.
У меня есть представление о функции повторения, но на самом деле я не знаю, как ее реализовать.





В 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();
}
}
}
Это будет работать очень быстро (за исключением мьютекса), но поскольку потоки не блокируются, он склонен к отсутствию удалений (например, при выполнении 1000 шагов с n_h = 4 может быть выполнено только 241 удаление вместо 250, как предполагалось), особенно если элементы удаляются чаще, чем добавляются. Кроме того, будет иметь значение скорость, с которой элемент может быть добавлен или удален - более быстрое добавление / удаление увеличивает вероятность промаха.
Если вы хотите привязать это к часам вашего процессора и иметь секунды t и n, отражающие время действительный в секундах «настенных часов», я бы рекомендовал взглянуть на 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 является разделяемой памятью, объявленной либо как указатель, либо явно объявленной как разделяемая память.
Оба этих метода могут (и, вероятно, будут) быть более неэффективными, чем однопоточный подход, если только добавление / удаление элемента не требует больших вычислительных затрат (т.е. если есть значительные вычисления, связанные с решением об удалении, или если элемент имеет большой объем памяти. след).
Лично синхронные подходы, подобные этому, когда потоки должны ждать друг друга, заставляют меня нервничать, потому что, если какой-либо из них зависает по какой-либо причине, все это зависает - в зависимости от приложения, которое может быть хуже, чем зависание только одного или нескольких потоков.
Надеюсь это поможет.
Очень полезный ответ
std::thread. убедитесь, что ресурсы, совместно используемые потоками, каким-либо образом защищены от одновременного доступа.std::mutexможет здесь помочь.