精华内容
下载资源
问答
  • 简谈一下时间轮(Time Wheel

    千次阅读 2016-08-10 16:47:49
      ...如果一个程序员不知道 Time Wheel,那么那个程序员一定不是个合格的程序员。...timer对于操作系统还是一个虚拟机语言或大型中间件都起着重要的作用,同时...Time Wheel翻译为时间轮,是用于实现定时器timer
    
    

     

    如果一个程序员不知道 Time Wheel,那么那个程序员一定不是个合格的程序员。

     

    timer对于操作系统还是一个虚拟机语言或大型中间件都起着重要的作用,同时timer算法的选择也直接影响着性能。

     

    Time Wheel翻译为时间轮,是用于实现定时器timer的经典算法,算法细节就不多说了,这里主要是看看Erlang中和Linux kernel的time wheel实现有哪些不同。

     

    Erlang中的Time Wheel实现文件是time.c,kernel中的实现文件是timer.c,好了,先看看kernel中的实现吧!

     

    Linux kernel中的time wheel这么多年一直没怎么改变,主要特点是以下几点:

    1)kernel中的timer是在softirq中执行

    2)多CPU同时执行,和process差不多,timer也可在cpu中migrate

    3)使用percpu

    4) 核心数据结构:

    1. struct tvec_base {  
    2.         spinlock_t lock;  
    3.         struct timer_list *running_timer;  
    4.         unsigned long timer_jiffies;  
    5.         unsigned long next_timer;  
    6.         struct tvec_root tv1;  
    7.         struct tvec tv2;  
    8.         struct tvec tv3;  
    9.         struct tvec tv4;  
    10.         struct tvec tv5;  
    11. } ____cacheline_aligned;  
     

    这里的base属于percpu数据,即每个cpu拥有一个base,这样每个cpu执行自己base里面的timer。这里有tv1/tv2/tv3/tv4/tv5,这几个vector维护着所有timer,每次加timer时根据timeout的时间分别加入到不同的vector中,tv1是最近的,tv5是最远的,kernel首先会在tv1中遍历timeout的timer,如果遍历完tv1,则从tv2中的timer list加到tv1中,如果tv2中的timer list用完后,再从tv3中取,注意tv3中的timer可以分布到tv1和tv2中,以此类推,实现代码如下:

    1. #define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)  
    2.   
    3. /** 
    4.  * __run_timers - run all expired timers (if any) on this CPU. 
    5.  * @base: the timer vector to be processed. 
    6.  * 
    7.  * This function cascades all vectors and executes all expired timer 
    8.  * vectors. 
    9.  */  
    10. static inline void __run_timers(struct tvec_base *base)  
    11. {  
    12.         struct timer_list *timer;  
    13.   
    14.         spin_lock_irq(&base->lock);  
    15.         while (time_after_eq(jiffies, base->timer_jiffies)) {  
    16.                 struct list_head work_list;  
    17.                 struct list_head *head = &work_list;  
    18.                 int index = base->timer_jiffies & TVR_MASK;  
    19.   
    20.                 /* 
    21.                  * Cascade timers: 
    22.                  */  
    23.                 if (!index &&  
    24.                         (!cascade(base, &base->tv2, INDEX(0))) &&  
    25.                                 (!cascade(base, &base->tv3, INDEX(1))) &&  
    26.                                         !cascade(base, &base->tv4, INDEX(2)))  
    27.                         cascade(base, &base->tv5, INDEX(3));  
    28.                 ++base->timer_jiffies;  
    29.                 list_replace_init(base->tv1.vec + index, &work_list);  
    30.                 while (!list_empty(head)) {  
    31.                         void (*fn)(unsigned long);  
    32.                         unsigned long data;  
    33.   
    34.                         timer = list_first_entry(head, struct timer_list,entry);  
    35.                         fn = timer->function;  
    36.                         data = timer->data;  
    37.   
    38.                         timer_stats_account_timer(timer);  
    39.   
    40.                         base->running_timer = timer;  
    41.                         detach_timer(timer, 1);  
    42.   
    43.                         spin_unlock_irq(&base->lock);  
    44.                         call_timer_fn(timer, fn, data);  
    45.                         spin_lock_irq(&base->lock);  
    46.                 }  
    47.         }  
    48.         base->running_timer = NULL;  
    49.         spin_unlock_irq(&base->lock);  
    50. }  
    51.   
    52. static int cascade(struct tvec_base *base, struct tvec *tv, int index)  
    53. {  
    54.         /* cascade all the timers from tv up one level */  
    55.         struct timer_list *timer, *tmp;  
    56.         struct list_head tv_list;  
    57.   
    58.         list_replace_init(tv->vec + index, &tv_list);  
    59.   
    60.         /* 
    61.          * We are removing _all_ timers from the list, so we 
    62.          * don't have to detach them individually. 
    63.          */  
    64.         list_for_each_entry_safe(timer, tmp, &tv_list, entry) {  
    65.                 BUG_ON(tbase_get_base(timer->base) != base);  
    66.                 internal_add_timer(base, timer);  
    67.         }  
    68.   
    69.         return index;  
    70. }  
     

    可以看出,即使你加了很多长时间的timer,kernel的timer性能并没有减少,因为长时间time被分布到不同的vector中,因此Linux kernel中的time wheel算法适合大容量的timer应用场景。

    (注意kernel中每个base的lock用的是spin lock,而不是mutex,下面会讲到)

     

     

    下面再来看看Erlang中的timer实现,erlang普遍应用于并发量比较高的场景,erlang的process通信是通过message,message的发送接收显然离不开timer,erlang甚至把timer提升到语言语法的层次,从此可看出timer在

    erlang中使用是多么的广泛。

    和Linux kernel的time wheel比较,erlang有以下几点不同:

    1)erlang的timer执行过程是在erlang process schedule时发生,而不是像很多中间件timer实现那样用单独的线程,这是有历史原因的(Erlang应兼顾到plain cpu的情形)。

    2)erlang的scheduler线程可以有多个,所以timer wheel需要lock的支持

    3)没有percpu,由于erlang在user space,所以percpu是个很难的问题,原因是抢占的问题,kernel实现的percpu可以显著提高性能,但也是有代价的,代价就是在很多percpu的处理过程中要关闭抢占,这也就是为什么RT kernel的人比较头疼percpu的原因。而在用户空间,抢占被操作系统强制执行,导致用户空间程序无法使用percpu。

    4)Erlang中time wheel没有像Linux kernel那样把timeout根据相对时间挂载到tv1/tv2/tv3/tv4/tv5中,但是erlang中的wheel slot却比较大(kernel中的slot是16或64),可以是8192或65536,这在一定程度上缓解了大量长时间timer对性能带来的影响,如果把 每个wheel的slot的间隔时间算作是1ms,wheel算作8192,那么几乎是8s一个wheel就遍历完,如果程序中有大量的timer超时时间大于8s,那么那些timer就会对8192取模挂载在相应的slot下,这就意味着每次遍历是会有很多并未超时的timer被访问到,而这在Linux kernel中则不存在。核心代码如下:

    1. static ERTS_INLINE void bump_timer_internal(erts_short_time_t dt) /* PRE: tiw_lock is write-locked */  
    2. {  
    3.     Uint keep_pos;  
    4.     Uint count;  
    5.     ErlTimer *p, **prev, *timeout_head, **timeout_tail;  
    6.     Uint dtime = (Uint) dt;  
    7.   
    8.     /* no need to bump the position if there aren't any timeouts */  
    9.     if (tiw_nto == 0) {  
    10.         erts_smp_mtx_unlock(&tiw_lock);  
    11.         return;  
    12.     }  
    13.   
    14.     /* if do_time > TIW_SIZE we want to go around just once */  
    15.     count = (Uint)(dtime / TIW_SIZE) + 1;  
    16.     keep_pos = (tiw_pos + dtime) % TIW_SIZE;  
    17.     if (dtime > TIW_SIZE) dtime = TIW_SIZE;  
    18.   
    19.     timeout_head = NULL;  
    20.     timeout_tail = &timeout_head;  
    21.     while (dtime > 0) {  
    22.         /* this is to decrease the counters with the right amount */  
    23.         /* when dtime >= TIW_SIZE */  
    24.         if (tiw_pos == keep_pos) count--;  
    25.         prev = &tiw[tiw_pos];  
    26.         while ((p = *prev) != NULL) {  
    27.             ASSERT( p != p->next);  
    28.             if (p->count < count) {     /* we have a timeout */  
    29.                 /* remove min time */  
    30.                 if (tiw_min_ptr == p) {  
    31.                     tiw_min_ptr = NULL;  
    32.                     tiw_min = 0;  
    33.                 }  
    34.   
    35.                 /* Remove from list */  
    36.                 remove_timer(p);  
    37.                 *timeout_tail = p;      /* Insert in timeout queue */  
    38.                 timeout_tail = &p->next;  
    39.             }  
    40.             else {  
    41.                 /* no timeout, just decrease counter */  
    42.                 p->count -= count;  
    43.                 prev = &p->next;  
    44.             }  
    45.         }  
    46.         tiw_pos = (tiw_pos + 1) % TIW_SIZE;  
    47.         dtime--;  
    48.     }  
    49.     tiw_pos = keep_pos;  
    50.     if (tiw_min_ptr)  
    51.         tiw_min -= dt;  
    52.   
    53.     erts_smp_mtx_unlock(&tiw_lock);  
     

    综上比较,在面对大容量timer的情况下Linux kernel的time wheel算法会比Erlang更有效率一些。最后还有一点要注意,Erlang的time wheel使用的lock是mutex(上面说过Linux kernel使用spin lock),在这里那种lock会更适合time wheel呢?个人觉得spin lock会好些,毕竟临界区代码处理应该会很快。当然如果erlang中ethread mutex使用的是mutex spin机制(mutex使用的是futex,在进入kernel futex前,进行spin lock很短一段时间),那就无所谓了。

    展开全文
  • Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。Python的第一个主流打包格式是.egg文件,现在大家庭中又有了一个叫做Wheel(*.whl)的新成员。wheel“被设计成包含PEP 376兼容安装(一种非常接近于...

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。

    Python的第一个主流打包格式是.egg文件,现在大家庭中又有了一个叫做Wheel(*.whl)的新成员。wheel“被设计成包含PEP 376兼容安装(一种非常接近于磁盘上的格式)的所有文件”。在本文中,我们将学习如何创建一个wheel以及如何在virtualenv中安装wheel。

    起步

    你需要pip来创建wheel,要学习安装pip,我强烈推荐阅读pip的安装页面。如果你已经安装了pip,那么你需要把它升级到最新版本。你只需要做这些:在一个控制台窗口中,输入以下命令:pip install --upgrade pip

    完成以上工作后,我们就准备学习创建wheel了!

    创建wheel

    首先,你需要安装wheel包:pip install wheel

    这相当的容易!下一步,我们将使用unidecode包来创建我们的第一个wheel,因为当我在写本文的时候,我们的wheel包还没有创建出来,接下来我会在多个项目中使用这个包。pip wheel --wheel-dir=my_wheels Unidecode

    现在,你在my_wheels文件夹中有了名字为Unidecode-0.04.14-py26-none-any.whl的wheel,让我们来学习安装新创建的wheel!

    安装Python wheel

    让我们创建一个virtualenv来进行测试,你可以在这里读取更多关于virtualenv的信息。一旦你安装了virtualenv,使用下面的命令来测试:virtualenv test

    这将为我们创建一个包含pip的可试验虚拟沙箱,在继续下一步之前,确信运行了Scripts文件夹中的activate来使能virtualenv。现在virtualenv没有包括wheel,所以你需要再次安装wheel:pip install wheel

    一旦wheel安装,我们就使用如下命令来安装我们之前创建的wheel:pip install --use-wheel --no-index --find-links=path/to/my_wheels Unidecode

    为了测试运行是否正常,从你virtualenv的Scripts文件夹中运行Python并且尝试导入unidecode。如果它正常导入,那么你成功的安装了你之前创建的wheel!

    注解:我开始的时候安装了一个麻烦多多的旧版本virtualenv。确信你升级到了最新版本,或者你花费大量时间去折腾让它正常工作。

    *.whl文件有一点与*.egg文件相似:实际上它们都是“伪装的”*.zip文件。如果你将*.whl文件名扩展改为*.zip,你就可以使用你的zip应用程序打开它,并且可以查看它包含的文件和文件夹。

    总结

    现在你已经准备好创建你自己的wheel了,那就像为你自己的快速安装项目创建本地仓库的一个很好地方法。你可以创建多个不同的wheel仓库,这便与在不同测试版本之间切换。当与virtualenv结合后,你就会有一个很便捷的方法,通过该方法,你看到新版本的依赖如何在不需要多次下载它们的情况下作用于你的项目。

    英文原文:http://www.blog.pythonlibrary.org/2014/01/10/python-packaging-wheel/

    译者:pyBean

    展开全文
  • Linux中的Wheel组的作用

    2014-05-11 12:57:00
    原文:... Linux中的Wheel组的作用(用自己的话翻译的) (原文) Wheel The wheel group is a legacy from UNIX. When a server had to be maintained at a hig...
    原文:http://www.360doc.com/content/11/0505/10/4644186_114496525.shtml

    Linux中的Wheel组的作用(用自己的话翻译的)

     

    (原文) 

    Wheel

    The wheel group is a legacy from UNIX. When a server had to be maintained at a higher level than the day-to-day system administrator, root rights were often required. The 'wheel' group was used to create a pool of user accounts that were allowed to get that level of access to the server. If you weren't in the 'wheel' group, you were denied access to root. I'll show a couple of ways to use membership of 'wheel' to limit the amount of havoc you can wreck on your system.

    Most modern-day Linux distro's still use this concept of grouping people to assign different levels of administrative access, but to my knowledge the 'wheel' group is not necessarily used to that purpose. I like to be old-fashioned from time to time, and so I resurrected the use of 'wheel'. Add yourself to wheel when creating your account (use 'wheel' as your primary group) or use vigr to edit the file /etc/group and put your name to the end of the line starting with wheel - like this:

     wheel::10:root,alien

    The vigr command is a safe way of editing the group file in a multi-user environment. Of course, if there's no one working on your box except yourself, you might just as well use plain vi.

     ======================================================

     (KC的译文)
     Wheel组
     Wheel组是Unix系统一个遗留物。当服务器需要做比日常例行维护更高级的工作的时候,就经常需要用到root根权限了。而这个wheel组就是建立用来归纳一些特殊的系统用户用的,这其中的用户都或多或少地拥有root的部分功能和权限。也就是说如果你不是wheel组成员,那就没有root身上任何的特权。也因为这样,使用wheel组成员用户的话,会尽量减少对系统“摧毁性”破坏的概率和风险。如今大多数的Linux发行版本中,仍然保留了wheel这个组,虽然它已经不像当初设计出来的那样必要了,但是有些老玩家还是忠于这种旧式经典风格的,所以他们经常还是依旧让wheel组发挥着以往的作用。他们是这样做的:在建立他们自己的用户时,将其添加入wheel组中(用wheel组作为用户的主组),或者使用vigr来编辑/etc/group文件,将他们的用户名追加到wheel组那行的末尾,就像这样:
     wheel::10:root,kc
     在多用户环境中编辑组配置文件时,vigr是一种较为妥当安全的这个命令工具。当然,当然,如果除了你自己之外没有其它人共用主机时,也可用直接用vi编辑器来做啦。

    转载于:https://www.cnblogs.com/zhaojk2010/p/3721684.html

    展开全文
  • Color Wheel for Mac是一款可直接输出Web颜色代码的取色工具,通过方便的Hex/RGB/Float/HSL翻译提供即时访问标准Mac OS X的ColorWheel,任何网页设计师的工具箱都应该有它,将它配置在工具栏上,并打开一个全局热键...

    Color Wheel for Mac是一款可直接输出Web颜色代码的取色工具,通过方便的Hex/RGB/Float/HSL翻译提供即时访问标准Mac OS X的ColorWheel,任何网页设计师的工具箱都应该有它,将它配置在工具栏上,并打开一个全局热键,使用方便又快捷。

    Color Wheel for Mac软件包括:

    数字色轮-我们独特的图形设计工具。

    经典色轮-经典,通用的色轮版本。

    抽象色轮-抽象绘画的专业颜色选择(“数字色轮”工具中抽象色方案的简化版本)。

    色彩组合-用于数字设计和抽象艺术的许多专业调色板。

    色板-用于根据季节和心情选择颜色的工具。

    以上就是小编给大家带来Color Wheel for Mac取色工具,有喜欢的千万不要错过哦!更多好用的Mac软件,尽在macz,有兴趣的可以来看看。 

    展开全文
  • [Violation ] Added non-passive event listener to ascroll- blocking 'mousewheel’event Consider marking event handler ...翻译: [冲突]在ascroll中添加了非被动事件侦听器-阻塞“mousewheel”事件考虑将事件处理
  • 谷歌控制台 提示: [Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive 翻译 违反:没有添加...
  • [Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Conside 翻译过来如下: 违反:没有添加被动事件监听器来阻止'touchstart'事件,请考虑添加事件管理者'passive',以使...
  •   ...netty中的Timer管理,使用了的Hashed time Wheel的模式,Time Wheel翻译为时间轮,是用于实现定时器timer的经典算法。 我们看看netty的HashedWheelTimer的一个测试的例子,先new一个H...
  • http://www.tianjiaguo.com/programming-language/java-language/netty%E5%AE%9A%E6%97%B6%E5%99%A8hashedwheeltimer/ netty中的Timer管理,使用了的Hashed time Wheel的模式,Time Wheel翻译为时间轮,是用于实现...
  • netty定时器HashedWheelTimer

    千次阅读 2013-11-28 09:54:45
    netty中的Timer管理,使用了的Hashed time Wheel的模式,Time Wheel翻译为时间轮,是用于实现定时器timer的经典算法。 我们看看netty的HashedWheelTimer的一个测试的例子,先new一个HashedWheelTimer,然后调用它的...
  • netty中的Timer管理,使用了的Hashed time Wheel的模式,Time Wheel翻译为时间轮,是用于实现定时器timer的经典算法。算法的核心是将时间划分结合,可能在时间准确性上会比一般的Timer差。 我们看看netty的...
  • 某度翻译 将非被动事件侦听器添加到滚动阻止“鼠标滚轮”事件。考虑将事件处理程序标记为“被动”以使页更具响应性 解决: https://blog.csdn.net/dj0379/article/details/52883315 Google公布了一个让页面滑动更...
  • 外文翻译 stus MVC

    2010-05-28 15:02:31
    Why re-invent the wheel, or a tag library? If you cannot find something you need in the library, contribute. In addition, Struts provides a starting point if you are learning JSP tag technology. • ...
  • operate or control a ..."drive a car or bus""Can you drive this four-wheel truck?"travel or be transported in a vehicle;"We drove to the university every morning""They motored to London for the t...
  • 2006年mcmB题翻译

    2011-02-07 00:09:00
    准备mcm中。。。 ————————————...PROBLEM B: Wheel Chair Access at Airports One of the frustrations with air travel is the need to fly through multiple airports, and each stop generally re
  • 本文地址:... 原文地址:http://adomas.org/javascript-mouse-wheel/ 原文作者:unknown 最近正在做评论模块的image LazyLoad(图片资源延迟加载/按需加载),其中涉及到一些mouse scroll操作。老
  • Phaser教程翻译-制作一个幸运大转轮

    千次阅读 2015-09-18 15:33:39
    原帖地址:Create a wheel of fortune for your HTML5 games with Phaser in only a few lines
  • 原文地址Create a Wheel of Fortune in this tutorial笔者寄语前言
  • 李莫愁 Don't Worry Lee   李寻欢 Be Happy Lee   常遇春 Always Meet Spring   杨不悔 No ... 王重阳 Double Sun King   金轮法王 Golden Wheel-in-law
  • ColorWell_7.1.7.zip

    2020-01-21 10:15:20
    ColorWell 是一款可直接输出Web颜色代码的取色工具,通过方便的Hex/RGB/Float/HSL翻译提供即时访问标准Mac OS X 的Color Wheel,任何网页设计师的工具箱都应该有它,将它配置在工具栏上,并打开一个全局热键,使用...
  • 事先在网上搜索了一大圈,头都大了,看到那么多文章写道在python里安装psycopg2的各种坑和各种麻烦,各种不...翻译过来就是:“如果你的pip版本支持wheel包,那么可以仅仅允许pip命令即可安装一个二进制的Psycopg版本,
  • Android最佳实践指南

    2016-01-09 10:51:00
    Updated on 2016/1/6 修正了一些翻译段落欢迎转载,但请保留译者链接:http://www.jianshu.com/p/613d28a3c8a0 Lessons learned from ... Avoid reinventing the wheel by following these guidelines. If you...
  • Unity 车轮碰撞器的入门使用(二)

    千次阅读 2018-08-13 22:39:51
    Wheel Damping Rate:车轮的阻尼值大小,必须要大于0。可以控制车辆抖动,减少震动 Suspension Distance:官方翻译为:车轮悬挂的最大伸长距离,在局部空间测量。悬架总是通过局部Y轴向下延伸 Force App Poi...
  • iOS 中如何缓存服务器响应?

    千次阅读 2015-04-23 17:13:31
    大致翻译自:How to cache server responses in iOS apps通常与服务器通过 ...Both are the source of much reinventing the wheel.这些都是很常见的问题,所以不要吃惊。iOS有我们所需的APIs来实现响应缓存和离线模式。
  • Unity3d物理汽车

    2012-12-29 12:06:00
    这个是一个朋友写的并翻译的关于Unity3d物理汽车的资料。不错 。。。分享下: http://www.cnblogs.com/alongu3d/archive/2012/12/26/wuliche2.html 转载于:...
  • 自行车轮组:基本几何与动力学

    千次阅读 2017-12-15 20:34:27
    翻译的外国论坛文章,源地址:https://whosatthewheel.com/2017/11/12/the-bicycle-wheel-basic-dynamics/正文直至今日,在一个知识遍布并能广泛获取的年代,我还在读一些像自行车轮子这么简单的一些废话(a lot of ...
  • JAVA接口介绍

    2016-10-05 15:02:01
    JAVA接口介绍官方文档的尝试性翻译:如你已经学到的,对象通过定义函数的方法与外部交流。函数为对象与外界的接口。例如,你电视机前的按钮,是你和它的塑料外壳电布线的接口。你按下了“电源”按钮来控制电视机的关...
  • 来源于官方网站的翻译 **Conda和pip通常被认为是几乎相同的。**尽管这两个工具的某些功能重叠,但是它们是经过设计的,应用于不同的目的。Pip是Python包装管理局推荐的工具,可用于从Python软件包索引PyPI安装软件包...
  • 《软件调试》与《Windows高级调试》比较之我见 我是在2007年 11月听说Advanced Windows Debugging(姑且翻译为《Windows高级调试》,简称AWD)这本书的。一个朋友和我说有一本书和你在写的书很相似,已经要出版了。...

空空如也

空空如也

1 2
收藏数 38
精华内容 15
关键字:

wheel翻译