spinlock 的很多线程抢占时的性能优化,补充 pthread
来源:互联网 发布:三维迷宫软件 编辑:程序博客网 时间:2024/05/16 09:50
罗索实验室
- 主页
- 流媒体开发
- 音视频技术
- 嵌入式开发
- 基础技术
- 杂项技术
- 管理学院
- 啰嗦IT
- 大杂烩
热门标签
- 视频监控技术 ffmpeg ce 264 ffmpeg .264 码流分析
spinlock 的很多线程抢占时的性能优化,补充 pthread mutex 和 f
微博里面看到有人说spinlock线程比较多在以前抢占锁时性能比价差。因为之前搜索过c++了spinlock,大多解决办法就是 那种指数的规避的办法咯,就是如果实在不行,就先让cpu指数的等待时间空转几次,实在还是拿不到锁在休眠。可以去看nginx的 core 代码的spinlock文件的实现。像那些boost的spinlock也差不多大,之前说过了。 这样很多个线程都在抢那个锁的时候,不至于都在那里忙等,比较好一点。
在网上搜索一下 “spinlock Exponential Backoff” 应该就可以找到相关资料了。
不过 “spinlock Exponential Backoff” 也还是不够好,呵呵,所以有人又搞了 queue lock。 就是大家不要抢咯,一个个排队来拿锁了。应该是这样吧? 就是少了争抢的。我最讨厌那种饭堂吃饭不排队的人了,大家都在那里抢,谁都吃不到,呵呵
去网上搜索应该可以找到资料吧。“Anderson Queue Lock” “CLH Queue Lock” 还是什么的。
下面这篇文章里面都有提到上面那些知识的,可以先去看一下下面这个。
Spin Locks and Contention By Guy Kalinski
http://www.cs.tau.ac.il/~afek/Spin%20Locks%20and%20Contention.ppt
========================================================
大家很喜欢那spinlock和 mutex 来比较,我个人也是比较喜欢spinlock一点,可能linux内核代码看多了,总是觉得spinlock性能要好。不过这应该分场合,如果按照下面这个。
比如这篇 Pthreads并行编程之spin lock与mutex性能对比分析
http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/
--------------------------
Fast Userspace Mutexes
用户使用futex的时候,大多的锁操作都是在用户操作里面进行的,不用进入内核,所以性能很好吧。然后有碰到大家都在竞争这个锁的时候,才通过futex系统调用进入内核,内核就会把竞争者做个排队,放到队列里面去。然后唤醒的时候,从队列里面依次唤醒。
看来 “排队”是解决“拥挤”(锁竞争)的好办法啊。
根据futex的实现,如果锁竞争不激烈,大多的操作都是在用户级完成的(也是那些原子汇编指令吧),这个跟spinlock应该没有太多的区别,两者 性能不会相差的太大。 两者的区别是futex碰到竞争马上会进入内核去排队,而spinlock会忙等一会在那里重试,然后指数级的等待时间都不到,到了一个固定的 timeout之后才主动的让内核有切换的机会。这两种办法有各自的优点吧,很难说哪个更好一些。不过两种不同的办法,初略看来是会导致一点不同的区 别,futex那种进入内核线程“排队”的做法应该是可以保证各个线程的公平性的,spinlock这种嘛应该是不能保证线程的公平性的,如果有一个线程 一直在那里循环很快的拿锁然后释放可能大多时间都会被他抢去了,其他的线程可能很难抢到锁,导致“饥饿”状态。
-------------------------
http://lxr.linux.no/linux/Documentation/robust-futexes.txt
这篇文章主要将使用futex的进程意外退出的时候,怎么快速恢复锁的状态,不能拿锁,然后又挂了,别人也没法用了。 不过开始的对futex的介绍还是写的挺好的。
11A futex is in essence a user-space address, e.g. a 32-bit lock variable
12field. If userspace notices contention (the lock is already owned and
13someone else wants to grab it too) then the lock is marked with a value
14that says "there's a waiter pending", and the sys_futex(FUTEX_WAIT)
15syscall is used to wait for the other guy to release it. The kernel
16creates a 'futex queue' internally, so that it can later on match up the
17waiter with the waker - without them having to know about each other.
18When the owner thread releases the futex, it notices (via the variable
19value) that there were waiter(s) pending, and does the
20sys_futex(FUTEX_WAKE) syscall to wake them up. Once all waiters have
21taken and released the lock, the futex is again back to 'uncontended'
22state, and there's no in-kernel state associated with it. The kernel
23completely forgets that there ever was a futex at that address. This
24method makes futexes very lightweight and scalable.
---------------------------
SYSCALL_DEFINE6(futex
return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
------------------------
2628long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
2629 u32 __user *uaddr2, u32 val2, u32 val3)
2643 switch (cmd) {
2644 case FUTEX_WAIT:
2645 val3 = FUTEX_BITSET_MATCH_ANY;
2646 case FUTEX_WAIT_BITSET:
2647 ret = futex_wait(uaddr, flags, val, timeout, val3); ///等待
2648 break;
2649 case FUTEX_WAKE:
2650 val3 = FUTEX_BITSET_MATCH_ANY;
2651 case FUTEX_WAKE_BITSET:
2652 ret = futex_wake(uaddr, flags, val, val3); //唤醒
-------------------------------
static int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val,
ret = futex_wait_setup(uaddr, val, flags, &q, &hb);
1902 /* queue_me and wait for wakeup, timeout, or a signal. */
1903 futex_wait_queue_me(hb, &q, to); ////一直等在这里等待唤醒了,应该
if (!unqueue_me(&q))
if (!signal_pending(current)) //被信号意外唤醒的,跳到开头再次重试
---------------------------------
1752/**
1753 * futex_wait_queue_me() - queue_me() and wait for wakeup, timeout, or signal
1754 * @hb: the futex hash bucket, must be locked by the caller
1755 * @q: the futex_q to queue up on
1756 * @timeout: the prepared hrtimer_sleeper, or null for no timeout
1757 */
1758static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
1759 struct hrtimer_sleeper *timeout)
1760{
1761 /*
1762 * The task state is guaranteed to be set before another task can
1763 * wake it. set_current_state() is implemented using set_mb() and
1764 * queue_me() calls spin_unlock() upon completion, both serializing
1765 * access to the hash list and forcing another memory barrier.
1766 */
1767 set_current_state(TASK_INTERRUPTIBLE);
1768 queue_me(q, hb);
-------------------------
1478/**
1479 * queue_me() - Enqueue the futex_q on the futex_hash_bucket
1480 * @q: The futex_q to enqueue
1481 * @hb: The destination hash bucket
1482 *
1483 * The hb->lock must be held by the caller, and is released here. A call to
1484 * queue_me() is typically paired with exactly one call to unqueue_me(). The
1485 * exceptions involve the PI related operations, which may use unqueue_me_pi()
1486 * or nothing if the unqueue is done as part of the wake process and the unqueue
1487 * state is implicit in the state of woken task (see futex_wait_requeue_pi() for
1488 * an example).
1489 */
1490static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
1491 __releases(&hb->lock)
1492{
1493 int prio;
1494
1495 /*
1496 * The priority used to register this element is
1497 * - either the real thread-priority for the real-time threads
1498 * (i.e. threads with a priority lower than MAX_RT_PRIO)
1499 * - or MAX_RT_PRIO for non-RT threads.
1500 * Thus, all RT-threads are woken first in priority order, and
1501 * the others are woken last, in FIFO order.
1502 */
1503 prio = min(current->normal_prio, MAX_RT_PRIO);
1504
1505 plist_node_init(&q->list, prio);
1506 plist_add(&q->list, &hb->chain); ///加到等待队列里面去,plist是一个优先级队列,
1507 q->task = current;
1508 spin_unlock(&hb->lock);
1509}
(widebright)- 上一篇:apt-get软件包管理
- 下一篇:LInux AIO相关知识
- 收藏
- 挑错
- 推荐
- 打印
- 相关文章
- linux多线程设计
- pthread_kill和pthread_cancel
- 线程属性pthread_attr_t简介
- 使用 pthread_testcancel 作为pthread_cancel 时 线程的退出点函
- 线程模型
- Linux下的线程技术
- 解决了一个隐蔽的内存泄漏——pthread_create后没有detach导致内
- linux线程终止方式
- posix多线程函数速查
- 用Pthread Semophore实现生产者消费者同步
- 发表评论
- 最新评论进入详细评论页>>
- 推荐内容
- linux多线程设计
linux多线程设计是指基于Linux操作系统下的多线程设计,包括多任务程序的设计,并发程...
- 服务器高性能程序 磁盘I/O篇
Linux kernel提供了四个调度器供用户选择。他们是noop,cfq,deadline,as。可以在系统启...
- V4L2 camera 驱动 capture测试程序
这个测试程序是根据vivi驱动hard code的, 并不一定适合其他的camera驱动.比如,我手...
- ld中文使用手册完全版
'ld'把一定量的目标文件跟档案文件连接起来,并重定位它们的数据,连接符号引用.一般,在...
- linux加载当前目录的动态库
linux的excutable在执行的时候缺省是先搜索/lib和/usr/lib这两个目录,然后按照ld.so....
- ALSA编程细节分析
Loong:之前写过基于ALSA的WAV播放录音程序。现在本想好好整理一下ALSA的编程思想,但...
- linux多线程设计
- 热点内容
- SecureCRT 5.0 注册码
- Linux上配置Unix ODBC连接Oracle
- 关于Linux的视频编程(v4l2编程)
- linux+firefox+ssh+autoproxy 翻
- 基于ALSA的WAV播放和录音程序
- 中国需要LINUX吗?
- The GNU Make Manual, for GNU m
- Linux 内存调试工具- Valgrind
- linux下获取当前目录
- Linux如何生成.a文件
本站文章除注明转载外,均为本站原创、整理或编译.所有文章欢迎任何形式的转载,但请注明作者及出处,尊重他人劳动成果!
若您对转载的文章(作者、来源、版权)有任何疑问,请告知,一定即时处理(abuse{at}rosoo.net)。
Some Rights Reserved 1998 - 2006 Rosoo.Net
Except where otherwise noted, content on this site is
licensed base a Creative Commons Attribution 2.5 License
流媒体开发 QQ群1:8655372
流媒体开发 QQ群2:117013601
- spinlock 的很多线程抢占时的性能优化,补充 pthread
- spinlock与中断、抢占的关系
- [转载]2.6内核抢占和spinlock的问题
- 抢占式内核与非抢占式内核中的自旋锁(spinlock)的区别
- iOS性能优化的一些操作(补充)
- linux 学习之路(学linux必看) 一场解决掉你所有性能优化困扰的大会,APMCon2017限时六折,抢占席位!>>> 5 收藏(170) 很多同学接触Linux不多,对Linux平台的开
- 线程的调度有抢占式或者非抢占
- 关于spinlock和mutex的性能差异
- pthread线程优先级的调度
- Linux_ pthread 线程的取消
- 线程的分离状态 pthread
- pthread线程优先级的调度
- 线程抢占cpu资源的一幕
- pthread线程编程--POSIX的线程机制
- 性能优化的一些经验(欢迎补充)
- 浏览器中DOM操作的性能优化【+待补充】
- MySQL性能优化的最佳经验,随时补充
- MySQL性能优化的最佳经验,随时补充
- MySQL的表分区
- Protocol Buffer Basics: C++
- 百亿亿级计算机遇与挑战
- 火柴拼接数字的游戏
- TR-069
- spinlock 的很多线程抢占时的性能优化,补充 pthread
- Qt中的QMessageBox类
- 自动化测试
- 关于增益
- Oracle 11g 新特性 -- DB_ULTRA_SAFE 参数 说明
- CSS定位position
- 圆角框的制作
- Android 自定义菜单
- POJ 3903 Stock Exchange