Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <thread>
- #include <mutex>
- #include <chrono>
- #include <random>
- #include <vector>
- #include <iostream>
- #include <exception>
- #include <atomic>
- #include <numeric>
- using namespace std::chrono_literals;
- class futex {
- public:
- futex() : is_locked(false) {}
- void lock();
- bool try_lock();
- void unlock();
- private:
- std::atomic_bool is_locked;
- bool a = false;
- };
- void futex::lock() {
- a = false;
- if (!is_locked.compare_exchange_strong(a, true))
- throw std::exception("Try to lock locked futex");
- }
- bool futex::try_lock() {
- a = false;
- return is_locked.compare_exchange_strong(a, true);
- }
- void futex::unlock() {
- a = true;
- if (!is_locked.compare_exchange_strong(a, false))
- throw std::exception("Try to unlock unlocked futex");
- }
- int variable_to_change = 0;
- futex my_futex;
- std::mutex my_mutex;
- void job1() {
- while(!my_futex.try_lock()) {
- std::this_thread::sleep_for(2s);
- }
- variable_to_change++;
- my_futex.unlock();
- }
- void job2() {
- while (!my_mutex.try_lock()) {
- std::this_thread::sleep_for(2s);
- }
- variable_to_change++;
- my_mutex.unlock();
- }
- int main() {
- std::vector<std::thread> threads1;
- std::vector<std::thread> threads2;
- std::chrono::steady_clock::time_point start, end;
- start = std::chrono::steady_clock::now();
- for (int i = 0; i < std::thread::hardware_concurrency() / 2; i++) {
- threads1.push_back(std::thread(job1));
- }
- end = std::chrono::steady_clock::now();
- std::cout << (end - start).count() << std::endl;
- start = std::chrono::steady_clock::now();
- for (int i = 0; i < std::thread::hardware_concurrency() * 2; i++) {
- threads2.push_back(std::thread(job2));
- }
- end = std::chrono::steady_clock::now();
- std::cout << (end - start).count() << std::endl;
- for (auto&& t : threads1)
- t.join();
- for (auto&& t : threads2)
- t.join();
- return 0;
- }
- // при запуске с количеством потоков std::thread::hardware_concurrency() / 2 время 70866807, 1055308 для фьютекса и мьютекса соответсвенно
- // при запуске с количеством потоков std::thread::hardware_concurrency() * 2 время 4044944, 8354921 для фьютекса и мьютекса соответсвенно
- // Возможно, это связано с устройством мьютекса, т.е. внутри мьютекса вызовы устроены так, что для потоков, количество которых не превосходит std::thread::hardware_concurrency(), использование мьютекса оптимально, например.
Advertisement
Add Comment
Please, Sign In to add comment