//---------------------------------------------------- // msgmutex.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 msg { class mutex { public: mutex() { id = check(msgget(IPC_PRIVATE, 0600)); unlock(); } ~mutex() { check(msgctl(id, IPC_RMID, nullptr)); } void lock() { check(msgrcv(id, &msg, 1, 1, 0)); } void unlock() { check(msgsnd(id, &msg, 1, 0)); } private: int id; struct msgbuf { long mtype; char mtext[1]; } msg = {1, {'\0'}}; }; } // namespace msg msg::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; } //----------------------------------------------------