1
0
mirror of https://github.com/tearshark/librf.git synced 2024-10-02 00:00:11 +08:00
librf/tutorial/test_async_mutex.cpp

209 lines
4.4 KiB
C++
Raw Normal View History

2020-03-26 17:35:12 +08:00
#include <chrono>
2017-09-24 14:01:30 +08:00
#include <iostream>
#include <string>
#include <thread>
#include <deque>
#include "librf.h"
using namespace resumef;
2020-03-18 21:46:55 +08:00
using namespace std::chrono;
2017-09-24 14:01:30 +08:00
2020-03-18 21:46:55 +08:00
static mutex_t g_lock;
static intptr_t g_counter = 0;
2017-09-24 14:01:30 +08:00
2020-03-18 21:46:55 +08:00
static const size_t N = 10;
2017-09-24 14:01:30 +08:00
2020-03-18 21:46:55 +08:00
//🔒-50ms-🔒🗝🗝-150ms-|
//-------------.........
static future_t<> test_mutex_pop(size_t idx)
{
for (size_t i = 0; i < N / 2; ++i)
2017-09-24 14:01:30 +08:00
{
{
batch_unlock_t _locker = co_await g_lock.lock(); //_locker析构后会调用对应的unlock()函数。
2020-03-18 21:46:55 +08:00
--g_counter;
std::cout << "pop :" << g_counter << " on " << idx << std::endl;
2017-09-24 14:01:30 +08:00
2020-03-18 21:46:55 +08:00
co_await 50ms;
batch_unlock_t _locker_2 = co_await g_lock;
2020-03-18 21:46:55 +08:00
--g_counter;
std::cout << "pop :" << g_counter << " on " << idx << std::endl;
2017-09-24 14:01:30 +08:00
}
2020-03-18 21:46:55 +08:00
co_await 150ms;
2017-09-24 14:01:30 +08:00
}
}
2020-03-18 21:46:55 +08:00
//🔒-50ms-🗝-50ms-🔒-50ms-🗝-50ms-|
//---------........---------.......
//方法之一
2020-03-18 21:46:55 +08:00
static future_t<> test_mutex_push(size_t idx)
2017-09-24 14:01:30 +08:00
{
2020-03-18 21:46:55 +08:00
for (size_t i = 0; i < N; ++i)
2017-09-24 14:01:30 +08:00
{
2020-03-18 21:46:55 +08:00
{
batch_unlock_t _locker = co_await g_lock.lock();
2017-09-24 14:01:30 +08:00
2020-03-18 21:46:55 +08:00
++g_counter;
std::cout << "push:" << g_counter << " on " << idx << std::endl;
co_await 50ms;
}
co_await 50ms;
2017-09-24 14:01:30 +08:00
}
}
static future_t<> test_mutex_try_push(size_t idx)
{
for (size_t i = 0; i < N; ++i)
{
{
while (!co_await g_lock.try_lock())
co_await yield();
++g_counter;
std::cout << "push:" << g_counter << " on " << idx << std::endl;
co_await 50ms;
co_await g_lock.unlock();
}
co_await 50ms;
}
}
static future_t<> test_mutex_timeout_push(size_t idx)
{
for (size_t i = 0; i < N; ++i)
{
{
while (!co_await g_lock.try_lock_for(10ms))
co_await yield();
++g_counter;
std::cout << "push:" << g_counter << " on " << idx << std::endl;
co_await 50ms;
co_await g_lock.unlock();
}
co_await 50ms;
}
}
2020-03-18 21:46:55 +08:00
//🔒-50ms-🗝-50ms-🔒-50ms-🗝-50ms-|
//---------........---------.......
static std::thread test_mutex_async_push(size_t idx)
{
return std::thread([=]
{
char provide_unique_address = 0;
for (size_t i = 0; i < N; ++i)
{
if (g_lock.try_lock_for(500ms, &provide_unique_address))
2020-03-18 21:46:55 +08:00
{
batch_unlock_t _locker(std::adopt_lock, &provide_unique_address, g_lock);
2020-03-18 21:46:55 +08:00
++g_counter;
std::cout << "push:" << g_counter << " on " << idx << std::endl;
std::this_thread::sleep_for(50ms);
2020-03-23 17:19:59 +08:00
//g_lock.unlock(&provide_unique_address);
2020-03-18 21:46:55 +08:00
}
std::this_thread::sleep_for(50ms);
}
});
}
static void resumable_mutex_synch()
2017-09-24 14:01:30 +08:00
{
go test_mutex_timeout_push(0);
2017-09-24 14:01:30 +08:00
go test_mutex_pop(1);
2017-10-01 10:33:08 +08:00
this_scheduler()->run_until_notask();
2020-03-18 21:46:55 +08:00
std::cout << "result:" << g_counter << std::endl;
}
static void resumable_mutex_async()
{
auto th = test_mutex_async_push(0);
std::this_thread::sleep_for(25ms);
go test_mutex_pop(1);
this_scheduler()->run_until_notask();
th.join();
std::cout << "result:" << g_counter << std::endl;
}
static future_t<> resumable_mutex_range_push(size_t idx, mutex_t a, mutex_t b, mutex_t c)
{
for (int i = 0; i < 10000; ++i)
{
batch_unlock_t __lockers = co_await mutex_t::lock(a, b, c);
2020-03-22 00:50:54 +08:00
assert(a.is_locked());
assert(b.is_locked());
assert(c.is_locked());
++g_counter;
2020-03-22 00:50:54 +08:00
//std::cout << "push:" << g_counter << " on " << idx << std::endl;
2020-03-22 00:50:54 +08:00
//co_await 5ms;
}
}
static future_t<> resumable_mutex_range_pop(size_t idx, mutex_t a, mutex_t b, mutex_t c)
{
for (int i = 0; i < 10000; ++i)
{
co_await mutex_t::lock(adopt_manual_unlock, a, b, c);
2020-03-22 00:50:54 +08:00
assert(a.is_locked());
assert(b.is_locked());
assert(c.is_locked());
--g_counter;
2020-03-22 00:50:54 +08:00
//std::cout << "pop :" << g_counter << " on " << idx << std::endl;
2020-03-22 00:50:54 +08:00
//co_await 5ms;
co_await mutex_t::unlock(a, b, c);
}
}
static void resumable_mutex_lock_range()
{
mutex_t mtxA, mtxB, mtxC;
//不同的线程里加锁也需要是线程安全的
std::thread push_th([&]
{
local_scheduler __ls__;
go resumable_mutex_range_push(10, mtxA, mtxB, mtxC);
go resumable_mutex_range_push(11, mtxA, mtxC, mtxB);
this_scheduler()->run_until_notask();
});
go resumable_mutex_range_pop(12, mtxC, mtxB, mtxA);
go resumable_mutex_range_pop(13, mtxB, mtxA, mtxC);
this_scheduler()->run_until_notask();
push_th.join();
std::cout << "result:" << g_counter << std::endl;
}
2020-03-18 21:46:55 +08:00
void resumable_main_mutex()
{
2020-03-22 02:05:14 +08:00
resumable_mutex_synch();
std::cout << std::endl;
2020-03-18 21:46:55 +08:00
2020-03-22 02:05:14 +08:00
resumable_mutex_async();
std::cout << std::endl;
resumable_mutex_lock_range();
2017-09-24 14:01:30 +08:00
}