首页
社区
课程
招聘
[原创]mutex实现与性能
发表于: 2022-2-23 22:22 16461

[原创]mutex实现与性能

2022-2-23 22:22
16461

大家好,我是东北码农。
今天讲讲工作中的事吧,领导要求调研一个事,mutex性能如何?mutex无竞争时和有竞争时效率如何?

我和领导汇报时,都习惯先说结论,领导可以很容易抓住重点,如果感兴趣就继续看。

结论如下:

mutex实现时,分用户态部分和内核态部分,分别承担不同的功能:

使用我们的老朋友strace命令来观察抢锁时的系统调用情况。

strace使用可以参考前面的文章:
如何使用strace
动手实现一个strace

测试代码:

strace看一下,lock unlock无系统调用(只有sleep时有系统调用)。

测试代码:

用strace看一下,此时会大量调用futex 系统调用,来等待(FUTEX_WAIT_PRIVATE)和唤醒(FUTEX_WAKE_PRIVATE)。

搞定!

欢迎大家使用常用聊天软件关注、评论交流~
如果大家觉得有用,求点赞、转发~

 
 
std::mutex g_lock;
void test_no_race()
{
    for(int i = 0;i < 10;++i)
    {
        g_lock.lock();
        usleep(100*1000);
        g_lock.unlock();
    }
}
std::mutex g_lock;
void test_no_race()
{
    for(int i = 0;i < 10;++i)
    {
        g_lock.lock();
        usleep(100*1000);
        g_lock.unlock();
    }
}
xjp@xxx:~/code/case/case30_c11_fence$ strace -f ./a.out
。。。
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
。。。
xjp@xxx:~/code/case/case30_c11_fence$ strace -f ./a.out
。。。
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
。。。
std::mutex g_lock;
 
void test_no_race()
{
    for(int i = 0;i < 10;++i)
    {
        g_lock.lock();
        usleep(100*1000);
        g_lock.unlock();
    }
}
 
void test_race()
{
    std::thread t1(test_no_race);
    std::thread t2(test_no_race);
 
    t1.join();
    t2.join();
}
std::mutex g_lock;
 
void test_no_race()
{
    for(int i = 0;i < 10;++i)
    {
        g_lock.lock();
        usleep(100*1000);
        g_lock.unlock();
    }
}
 
void test_race()
{
    std::thread t1(test_no_race);
    std::thread t2(test_no_race);
 
    t1.join();
    t2.join();
}
[pid   552] futex(0x7f61977959d0, FUTEX_WAIT, 553, NULL <unfinished ...>
[pid   554] <... set_robust_list resumed>) = 0
[pid   554] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   553] <... clock_nanosleep resumed>NULL) = 0
[pid   553] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
[pid   554] <... futex resumed>)        = 0
[pid   553] <... futex resumed>)        = 1
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   553] <... futex resumed>)        = 0
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   553] <... futex resumed>)        = 0
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   553] <... futex resumed>)        = 0
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   553] <... futex resumed>)        = 0
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   553] <... futex resumed>)        = 0
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] <... futex resumed>)        = 0
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   553] <... futex resumed>)        = 0
[pid   553] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   554] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   553] <... clock_nanosleep resumed>NULL) = 0
[pid   553] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   554] <... futex resumed>)        = 0
[pid   554] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   553] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
[pid   553] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
[pid   554] <... futex resumed>)        = 0
[pid   553] <... futex resumed>)        = 1
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   553] <... futex resumed>)        = 0
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   553] <... futex resumed>)        = 0
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   553] <... futex resumed>)        = 0
[pid   554] mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0 <unfinished ...>
[pid   553] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   554] <... mmap resumed>)         = 0x7f618e794000
[pid   554] munmap(0x7f618e794000, 25608192) = 0
[pid   554] munmap(0x7f6194000000, 41500672) = 0
[pid   554] mprotect(0x7f6190000000, 135168, PROT_READ|PROT_WRITE) = 0
[pid   554] madvise(0x7f6196794000, 8368128, MADV_DONTNEED) = 0
[pid   554] exit(0)                     = ?
[pid   554] +++ exited with 0 +++
[pid   553] <... clock_nanosleep resumed>NULL) = 0
[pid   553] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 0
[pid   553] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
[pid   553] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
[pid   553] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
[pid   553] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
[pid   553] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
[pid   553] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
[pid   552] futex(0x7f61977959d0, FUTEX_WAIT, 553, NULL <unfinished ...>
[pid   554] <... set_robust_list resumed>) = 0
[pid   554] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   553] <... clock_nanosleep resumed>NULL) = 0
[pid   553] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
[pid   554] <... futex resumed>)        = 0
[pid   553] <... futex resumed>)        = 1
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   553] <... futex resumed>)        = 0
[pid   554] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},  <unfinished ...>
[pid   553] futex(0x560716857060, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
[pid   554] <... clock_nanosleep resumed>NULL) = 0
[pid   554] futex(0x560716857060, FUTEX_WAKE_PRIVATE, 1) = 1
[pid   553] <... futex resumed>)        = 0

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-2-23 22:23 被assqqq编辑 ,原因: 忘写标题了
收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回