//---------------------------------------------------- // mqmutex.cc: mutex using message queues //---------------------------------------------------- #include "check.h" #include #include #include #include #include #include #include #include //---------------------------------------------------- using namespace std::literals; //---------------------------------------------------- const size_t N = 32; std::latch latch(N); std::atomic stop = false; //---------------------------------------------------- namespace mq { class mutex { public: mutex() { std::string path = "/" + std::to_string(std::random_device{}()); mq_attr attr = {0, 1, 1, 0}; id = check( mq_open(path.c_str(), O_CREAT | O_EXCL | O_RDWR, 0666, &attr)); unlock(); } ~mutex() { check(mq_close(id)); } void lock() { check(mq_receive(id, &msg, 1, 0)); } void unlock() { check(mq_send(id, &msg, 1, 0)); } private: mqd_t id; char msg = '\0'; }; } // namespace mq mq::mutex m; //---------------------------------------------------- void seccion_critica() { std::cout << "[" << std::this_thread::get_id() << "]: "; for (size_t i = 0; i < 10; ++i) std::cout << i; std::cout << '\n'; } //---------------------------------------------------- void hebra() { latch.arrive_and_wait(); while (!stop) { std::lock_guard l(m); if (!stop) seccion_critica(); } } //---------------------------------------------------- int main() { std::jthread threads[N]; for (auto &i: threads) i = std::jthread(hebra); std::this_thread::sleep_for(75ms); stop = true; } //----------------------------------------------------