#include #include #include #include #include #include #include "solution.cpp" static int failures = 0; #define CHECK(cond, name) do { if (cond) std::printf("ok %s\n", name); \ else { std::printf("FAIL %s (line %d)\n", name, __LINE__); ++failures; } } while (0) int main() { // Базовая дисциплина { BlockingQueue q(2); q.push(1); q.push(2); CHECK(q.size() == 2, "size() == 2 после двух push"); int v = 0; CHECK(q.pop(v) && v == 1, "pop -> 1 (FIFO)"); CHECK(q.pop(v) && v == 2, "pop -> 2 (FIFO)"); q.close(); CHECK(!q.pop(v), "после close и опустошения pop -> false"); bool threw = false; try { q.push(3); } catch (const std::runtime_error&) { threw = true; } CHECK(threw, "push после close -> std::runtime_error"); } // Продюсеры/потребители под нагрузкой { const int P = 4, C = 4, PER = 20000, C3 = 64; BlockingQueue q(C3); std::atomic pushed{0}; std::atomic sum{0}; std::atomic popped{0}; std::atomic over{0}; auto producer = [&](int pid) { for (int i = 0; i < PER; ++i) { q.push(pid * 1000000 + i); pushed.fetch_add(1, std::memory_order_relaxed); if (q.size() > C3) over.fetch_add(1, std::memory_order_relaxed); } }; auto consumer = [&](int) { int v = 0; while (q.pop(v)) { sum.fetch_add(v, std::memory_order_relaxed); popped.fetch_add(1, std::memory_order_relaxed); } }; std::vector ts; for (int i = 0; i < C; ++i) ts.emplace_back(consumer, i); std::this_thread::sleep_for(std::chrono::milliseconds(20)); for (int i = 0; i < P; ++i) ts.emplace_back(producer, i); std::this_thread::sleep_for(std::chrono::milliseconds(50)); while (pushed.load() < P * PER) std::this_thread::sleep_for(std::chrono::milliseconds(10)); q.close(); for (auto& t : ts) t.join(); long long expect = 0; for (int p = 0; p < P; ++p) for (int i = 0; i < PER; ++i) expect += (long long)p * 1000000 + i; std::printf(" (вставлено=%d, извлечено=%d, переполнений=%d)\n", pushed.load(), popped.load(), over.load()); CHECK(pushed.load() == P * PER, "все вставки выполнены (нет потерь)"); CHECK(popped.load() == P * PER, "извлечено ровно столько же (нет дублей/потерь)"); CHECK(sum.load() == expect, "сумма значений совпадает с эталоном"); CHECK(over.load() == 0, "size() не превышал capacity"); } std::printf(failures ? "\nFAILURES: %d\n" : "\nALL PASS\n", failures); return failures ? 1 : 0; }