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>
|
|
|
|
|
|
2021-11-01 17:59:08 +08:00
|
|
|
|
#include "librf/librf.h"
|
2017-09-24 14:01:30 +08:00
|
|
|
|
|
2021-11-01 17:59:08 +08:00
|
|
|
|
using namespace librf;
|
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
|
|
|
|
{
|
|
|
|
|
{
|
2020-03-29 14:31:07 +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;
|
|
|
|
|
|
2020-03-29 14:31:07 +08:00
|
|
|
|
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-19 17:46:10 +08:00
|
|
|
|
//方法之一
|
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
|
|
|
|
{
|
2020-03-29 14:31:07 +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
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-19 17:46:10 +08:00
|
|
|
|
static future_t<> test_mutex_try_push(size_t idx)
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < N; ++i)
|
|
|
|
|
{
|
|
|
|
|
{
|
2020-04-18 11:46:29 +08:00
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
auto result = co_await g_lock.try_lock();
|
|
|
|
|
if (result) break;
|
2020-03-19 17:46:10 +08:00
|
|
|
|
co_await yield();
|
2020-04-18 11:46:29 +08:00
|
|
|
|
}
|
2020-03-19 17:46:10 +08:00
|
|
|
|
|
|
|
|
|
++g_counter;
|
|
|
|
|
std::cout << "push:" << g_counter << " on " << idx << std::endl;
|
|
|
|
|
|
|
|
|
|
co_await 50ms;
|
|
|
|
|
co_await g_lock.unlock();
|
|
|
|
|
}
|
|
|
|
|
co_await 50ms;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-20 01:04:52 +08:00
|
|
|
|
static future_t<> test_mutex_timeout_push(size_t idx)
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < N; ++i)
|
|
|
|
|
{
|
|
|
|
|
{
|
2020-04-18 11:46:29 +08:00
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
auto result = co_await g_lock.try_lock_for(10ms);
|
|
|
|
|
if (result) break;
|
2020-03-20 01:04:52 +08:00
|
|
|
|
co_await yield();
|
2020-04-18 11:46:29 +08:00
|
|
|
|
}
|
2020-03-20 01:04:52 +08:00
|
|
|
|
|
|
|
|
|
++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)
|
|
|
|
|
{
|
2020-03-19 17:46:10 +08:00
|
|
|
|
if (g_lock.try_lock_for(500ms, &provide_unique_address))
|
2020-03-18 21:46:55 +08:00
|
|
|
|
{
|
2020-03-29 14:31:07 +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-19 17:46:10 +08:00
|
|
|
|
|
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
|
|
|
|
{
|
2020-03-20 01:04:52 +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;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-20 18:13:31 +08:00
|
|
|
|
static future_t<> resumable_mutex_range_push(size_t idx, mutex_t a, mutex_t b, mutex_t c)
|
|
|
|
|
{
|
2020-03-26 14:30:59 +08:00
|
|
|
|
for (int i = 0; i < 10000; ++i)
|
2020-03-20 18:13:31 +08:00
|
|
|
|
{
|
2020-03-29 14:31:07 +08:00
|
|
|
|
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());
|
2020-03-20 18:13:31 +08:00
|
|
|
|
|
|
|
|
|
++g_counter;
|
2020-04-18 23:05:26 +08:00
|
|
|
|
//std::cout << "push:" << g_counter << " on " << idx << std::endl;
|
|
|
|
|
//co_await 5ms;
|
2020-03-20 18:13:31 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static future_t<> resumable_mutex_range_pop(size_t idx, mutex_t a, mutex_t b, mutex_t c)
|
|
|
|
|
{
|
2020-03-26 14:30:59 +08:00
|
|
|
|
for (int i = 0; i < 10000; ++i)
|
2020-03-20 18:13:31 +08:00
|
|
|
|
{
|
2020-04-18 13:47:46 +08:00
|
|
|
|
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());
|
2020-03-20 18:13:31 +08:00
|
|
|
|
|
|
|
|
|
--g_counter;
|
2020-04-18 23:05:26 +08:00
|
|
|
|
//std::cout << "pop :" << g_counter << " on " << idx << std::endl;
|
|
|
|
|
//co_await 5ms;
|
2020-03-20 18:13:31 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void resumable_mutex_lock_range()
|
|
|
|
|
{
|
|
|
|
|
mutex_t mtxA, mtxB, mtxC;
|
|
|
|
|
|
|
|
|
|
//不同的线程里加锁也需要是线程安全的
|
|
|
|
|
std::thread push_th([&]
|
|
|
|
|
{
|
2020-03-31 15:30:45 +08:00
|
|
|
|
local_scheduler_t __ls__;
|
2020-03-20 18:13:31 +08:00
|
|
|
|
|
|
|
|
|
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-05-09 22:55:53 +08:00
|
|
|
|
std::cout << "begin resumable_mutex_synch()" << std::endl;
|
|
|
|
|
resumable_mutex_synch();
|
|
|
|
|
std::cout << std::endl;
|
2020-03-18 21:46:55 +08:00
|
|
|
|
|
2020-05-09 22:55:53 +08:00
|
|
|
|
std::cout << "begin resumable_mutex_async()" << std::endl;
|
|
|
|
|
resumable_mutex_async();
|
|
|
|
|
std::cout << std::endl;
|
2020-03-20 18:13:31 +08:00
|
|
|
|
|
2020-04-18 13:47:46 +08:00
|
|
|
|
std::cout << "begin resumable_mutex_lock_range()" << std::endl;
|
2020-03-20 18:13:31 +08:00
|
|
|
|
resumable_mutex_lock_range();
|
2017-09-24 14:01:30 +08:00
|
|
|
|
}
|
2020-09-23 22:56:51 +08:00
|
|
|
|
|
2021-11-02 17:15:17 +08:00
|
|
|
|
#if LIBRF_TUTORIAL_STAND_ALONE
|
2020-09-23 22:56:51 +08:00
|
|
|
|
int main()
|
|
|
|
|
{
|
|
|
|
|
resumable_main_mutex();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2021-11-02 17:15:17 +08:00
|
|
|
|
#endif
|