目录
- 1 概述
- 2 使用实例
- 3 接口使用
- 3.1 construct
- 3.2 lock
- 3.3 try_lock
- 3.4 try_lock_for
- 3.5 try_lock_until
- 3.6 unlock
1 概述
定时互斥是一种时间可锁定的对象,它设计用于在代码的关键部分需要独占访问时发出信号,就像常规互斥一样,但还支持定时尝试锁定请求。
因此,timed_mutex有两个额外的成员:try_lock_for和try_lock_until。
它保证是一个标准布局类。 标准布局类型是一种具有简单线性数据结构和访问控制的类型,可以很容易地用于与用其他编程语言(如C)编写的代码进行通信.
其类图如下:
2 使用实例
struct TimedFunction
{
volatile int counter = 0;
void fireworks(std::timed_mutex & muxtex)
{
while(!muxtex.try_lock_for(std::chrono::milliseconds(200)))
;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
++counter;
muxtex.unlock();
}
void waitUtil(std::timed_mutex & muxtex, int seconds)
{
std::chrono::time_point<std::chrono::system_clock> timePoint
= std::chrono::system_clock::now() + std::chrono::seconds(seconds);
std::cerr << "\n\nWait util " << seconds << " seconds... \n";
if(muxtex.try_lock_until(timePoint))
{
muxtex.unlock();
counter = 10;
}
else
counter = 5;
}
void sleepFor(std::timed_mutex & muxtex, int seconds)
{
muxtex.lock();
std::cerr << "\n\nSleep " << seconds << " seconds... \n";
std::this_thread::sleep_for(std::chrono::seconds(seconds));
muxtex.unlock();
}
};
void TimedMutexSuite::try_lock_for()
{
std::timed_mutex muxtex;
TimedFunction function;
std::thread threads[10];
for(int i = 0; i < 10; i++)
threads[i] = std::thread(&TimedFunction::fireworks, std::ref(function), std::ref(muxtex));
for(auto &thread : threads)
thread.join();
TEST_ASSERT_EQUALS(true, function.counter == 10)
std::cerr << "function.counter: " << function.counter << std::endl;
}
void TimedMutexSuite::try_lock_until()
{
std::timed_mutex muxtex;
TimedFunction function;
std::thread threads[2];
threads[0] = std::thread(&TimedFunction::sleepFor, std::ref(function), std::ref(muxtex), 10);
threads[1] = std::thread(&TimedFunction::waitUtil, std::ref(function), std::ref(muxtex), 5);
threads[0].join();
threads[1].join();
TEST_ASSERT_EQUALS(true, function.counter == 5)
threads[0] = std::thread(&TimedFunction::sleepFor, std::ref(function), std::ref(muxtex), 5);
threads[1] = std::thread(&TimedFunction::waitUtil, std::ref(function), std::ref(muxtex), 10);
threads[0].join();
threads[1].join();
TEST_ASSERT_EQUALS(true, function.counter == 10)
}
3 接口使用
3.1 construct
void addCount(std::timed_mutex & mutex, int & count)
{
mutex.lock();
count++;
mutex.unlock();
}
void TimedMutexSuite::construct()
{
std::timed_mutex muxtex;
int count = 0;
std::thread threads[10];
for(int i = 0; i < 10; i++)
threads[i] = std::thread(addCount, std::ref(muxtex), std::ref(count));
for(auto &thread : threads)
thread.join();
TEST_ASSERT_EQUALS(10, count)
}
3.2 lock
void TimedMutexSuite::lock()
{
std::timed_mutex muxtex;
int count = 10;
std::thread threads[10];
for(int i = 0; i < 10; i++)
threads[i] = std::thread(addCount, std::ref(muxtex), std::ref(count));
for(auto &thread : threads)
thread.join();
TEST_ASSERT_EQUALS(20, count)
}
3.3 try_lock
struct TimedFunction
{
volatile int counter = 0;
void add_10k_count(std::timed_mutex & muxtex)
{
for(int i = 0; i < 10000; i++)
{
if(muxtex.try_lock())
{
++counter;
muxtex.unlock();
}
}
}
};
void TimedMutexSuite::try_lock()
{
std::timed_mutex muxtex;
TimedFunction function;
std::thread threads[10];
for(int i = 0; i < 10; i++)
threads[i] = std::thread(&TimedFunction::add_10k_count, std::ref(function), std::ref(muxtex));
for(auto &thread : threads)
thread.join();
TEST_ASSERT_EQUALS(true, function.counter < (10 * 10000))
std::cerr << "function.counter: " << function.counter << std::endl;
}
3.4 try_lock_for
struct TimedFunction
{
volatile int counter = 0;
void fireworks(std::timed_mutex & muxtex)
{
while(!muxtex.try_lock_for(std::chrono::milliseconds(200)))
;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
++counter;
muxtex.unlock();
}
void waitUtil(std::timed_mutex & muxtex, int seconds)
{
std::chrono::time_point<std::chrono::system_clock> timePoint
= std::chrono::system_clock::now() + std::chrono::seconds(seconds);
std::cerr << "\n\nWait util " << seconds << " seconds... \n";
if(muxtex.try_lock_until(timePoint))
{
muxtex.unlock();
counter = 10;
}
else
counter = 5;
}
void sleepFor(std::timed_mutex & muxtex, int seconds)
{
muxtex.lock();
std::cerr << "\n\nSleep " << seconds << " seconds... \n";
std::this_thread::sleep_for(std::chrono::seconds(seconds));
muxtex.unlock();
}
};
void TimedMutexSuite::try_lock_for()
{
std::timed_mutex muxtex;
TimedFunction function;
std::thread threads[10];
for(int i = 0; i < 10; i++)
threads[i] = std::thread(&TimedFunction::fireworks, std::ref(function), std::ref(muxtex));
for(auto &thread : threads)
thread.join();
TEST_ASSERT_EQUALS(true, function.counter == 10)
std::cerr << "function.counter: " << function.counter << std::endl;
}
说明:
- try_lock_for 如果等待指定时间没有锁定返回false,否则返回true
3.5 try_lock_until
void TimedMutexSuite::try_lock_until()
{
std::timed_mutex muxtex;
TimedFunction function;
std::thread threads[2];
threads[0] = std::thread(&TimedFunction::sleepFor, std::ref(function), std::ref(muxtex), 10);
threads[1] = std::thread(&TimedFunction::waitUtil, std::ref(function), std::ref(muxtex), 5);
threads[0].join();
threads[1].join();
TEST_ASSERT_EQUALS(true, function.counter == 5)
threads[0] = std::thread(&TimedFunction::sleepFor, std::ref(function), std::ref(muxtex), 5);
threads[1] = std::thread(&TimedFunction::waitUtil, std::ref(function), std::ref(muxtex), 10);
threads[0].join();
threads[1].join();
TEST_ASSERT_EQUALS(true, function.counter == 10)
}
说明:
- try_lock_until 如果等到指定时间没有锁定返回false,否则返回true
3.6 unlock
void TimedMutexSuite::unlock()
{
std::timed_mutex muxtex;
int count = 20;
std::thread threads[10];
for(int i = 0; i < 10; i++)
threads[i] = std::thread(addCount, std::ref(muxtex), std::ref(count));
for(auto &thread : threads)
thread.join();
TEST_ASSERT_EQUALS(30, count)
}