科学网

 找回密码
  注册

tag 标签: 计数器

相关帖子

版块 作者 回复/查看 最后发表

没有相关内容

相关日志

[转载]再谈谈perl多线程使用问题[转载]
luhg 2015-3-4 17:28
如今多核计算服务器已经普及,在并行效率比较低和计算任务琐碎繁多的情况下,在一个节点内部进行多线程并行是个非常好的选择。Bash的多线程并行需要使用fifo的一个文件,不如使用perl语言更为方便。 下面是转载的使用perl编写的多线程脚本,可以使用它进行并行处理批量任务。 最近有一个“十万条视频URL迁移”项目,算了一下,如果用单线程跑的话,大概要花费10天的时间,因此决定用多线程。 程序比较简单,先定义一个wget的子函数,该函数只负责2个事情, 1;使用LWP模块,接受传递的URL,将该URL下载并存储在相关目录。 2:在下载完毕后,对线程计数器减1,然后退出函数。 然后在程序主进程中,循环读取URL列表,每读取一个url,则生成一个线程去完成这个下载,同时每对线程计数器进行累加,当达到一定阀值的时候,则需要等待线程计数器下降到阀值以内才能生成新的线程。 代码块如下 #!/usr/bin/perl use warnings; use strict; use threads; use threads::shared; use LWP; use LWP::Simple; use File::Basename; use File::Path; ##使用这个变量存储线程数量 my $thread_num : shared = 0; sub doWget { ### ### 获取传递过来的URL参数,然进行下载并存储在相关目录 ### 下载完毕在退出线程之后,需要将 $thread_num 变量减1. $thread_num --; return 1; } ###主程序负责读取URL列表并生成线程下载 for (my $i=0;$i @urllist ;$i ++ ) { ..... $maxthread = 20; ##允许开启线程最大数量 if ( $thread_num = $maxthread ){ my $thread = threads-create(\dowget,$url); $thread_num ++; ##生成线程后,需要把线程计数器加1 }else{ while( $thread_num $maxthread ){ sleep 5; ##进入while循环,判断线程数量是否已经小于线程阀值。 } $i --; #这里需要把 for循环中的参数 $i 减1,以保证不会漏掉url } } ##最后,程序在退出之前,也要检查线程数量,以保证线程全部下载完毕才能退出。 while( $thread_num != 0) { sleep 5; } ## 完毕。
个人分类: 计算机|2659 次阅读|0 个评论
[转载]网站计数器
dolphinzhu 2012-7-13 15:07
script language="JavaScript" !-- var caution = false function setCookie(name, value, expires, path, domain, secure) { var curCookie = name + "=" + escape(value) + ((expires) ? "; expires=" + expires.toGMTString() : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "") if (!caution || (name + "=" + escape(value)).length = 4000) document.cookie = curCookie else if (confirm("Cookie exceeds 4KB and will be cut!")) document.cookie = curCookie } function getCookie(name) { var prefix = name + "=" var cookieStartIndex = document.cookie.indexOf(prefix) if (cookieStartIndex == -1) return null var cookieEndIndex = document.cookie.indexOf(";", cookieStartIndex + prefix.length) if (cookieEndIndex == -1) cookieEndIndex = document.cookie.length return unescape(document.cookie.substring(cookieStartIndex + prefix.length, cookieEndIndex)) } function deleteCookie(name, path, domain) { if (getCookie(name)) { document.cookie = name + "=" + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + "; expires=Thu, 01-Jan-70 00:00:01 GMT" } } function fixDate(date) { var base = new Date(0) var skew = base.getTime() if (skew 0) date.setTime(date.getTime() - skew) } var now = new Date() fixDate(now) now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000) var visits = getCookie("counter") if (!visits) visits = 1 else visits = parseInt(visits) + 1 setCookie("counter", visits, now) document.write("您是第" + visits + "访客!") // -- /script 转自网站 http://www.cnblogs.com/zhouqi/archive/2009/06/08/1498474.html
个人分类: 网站建设|1930 次阅读|0 个评论
算法课上受到的启发
热度 2 Rein 2011-3-30 09:02
毕业半年,借复旦学报/复旦招生网的人气,也收到了差不多两位数本科低年级学弟学妹的咨询邮件,甚至高三小朋友的邮件。很多小朋友都在请教,怎么做研究,怎么发论文。其实这个问题我也在摸索,估计还只有一只脚入了门,另外一只脚还不知道该往哪儿踏。所以我建议小朋友问我不如去问老师……任何一个老师经验都比我丰富。不过,昨天上了一节网络算法课,对我的启发非常大。 我自以为自己算法水平非常强的。虽然从没得过什么国际金牌,但是大部分日常问题一眼就能看出问题的复杂度和基本算法思路。不过,昨天那节算法课让我觉得,我的算法即使不说是白学了,远远没有学到算法思考的方法。 昨天是第一课,讲算法设计的原则。老师先举了个问题,让大家来想该怎么做。一个路由器,希望能够对那些可能是“坏”的数据包进行标记,方便终端进行进一步的检查。一些安全专家统计了数据包中每个字符的频率,然后对每个字符给出了个阈值。如果一个数据包中该字符占的比例超过了这个阈值,那么就给这个数据进行标记。该算法用硬件实现。一个最简单的方法是每个字符一个一个计数器,每收到一个新的字符后计数器加1。数据包接收完整后再检查,是否有字符超过阈值。如果是的话进行标记。老师说,这个方法有个问题,收完了数据包后在从新扫描所有字符的计数器,复杂度就平白多了255。问大家有没有什么好的办法?(背景补充:硬件解决这个问题中,在收完整个数据包之前不知道数据包的长度。并且数据包长度的范围差距非常大) 这个问题当然不难。作为有良好算法基础的计算机学生,很快能想到,每次计数器加1时,计算该计数器和阈值的比值的最大值,然后和一个全局最大值进行比较。最后只要这个全局最大值超过包长度就可以对该数据包进行标记了。不过我选的这门课不是CS的,是EE的。老师说,做除法代价太大了,我们不能做除法。于是我就半傻眼了(也许再思考下有其他算法,不过上课进度还是相当快的)。 老师的做法让我大跌眼镜:老师说:这个问题定义的有问题。解决这个问题的方法是改变这个问题的定义。 最重要的是解决正确的问题,其次才是正确地解决问题。 这个问题的本质是对可疑的数据包进行标记,并且阈值也是人给的。与其使用和和包总长度的比例,不如使用和当前长度的比例,(需要特殊处理长度较小时的情况,取个max即可)。虽然解决的问题和原来不一样,但是最后效果其实没差。或者改进一下我刚刚的算法,与其可以除以一个任意的阈值,不如限制阈值的取值范围,使其可以用移位来实现,反正阈值都是人给的。通过改变问题,这个问题一下就简单而又容易地解决了。 在国内,如果老师布置这么一道作业题,你去把人家题目给改了,自然是零分。不过做研究,第一步则需要能够分析出问题的本质,从而提炼出“正确”的问题去解决。 有了第一步的找出问题,第二步就是 找到所有可以利用的条件 。拿TCP的拥塞控制举例。最早的TCP,利用的信息是丢包。即当数据包发生丢失时,肯定发生了拥塞,所以我们需要降低传输速率,降低的幅度为1/2。然而这个粒度实在是太粗了。进一步分析这个问题,知道丢包的原因是中间某路由器的缓冲区满了,所以才丢包。那么我们可以利用路由器的缓冲区的信息。现代很多路由器支持当队列长度在A到B之间时(A和B由路由器的控制者定义),对数据包进行标记。于是后来TCP利用的条件就是有数据包在路由器被标记,因为缓冲区增大超过了A,说明即将开始拥塞了,需要降低速率。SIGCOMM 10的一篇文章提出来的DCTCP。思想仍然是利用被路由器标记的数据包。不过,他利用了更多的条件,即统计了在一个窗口中被标记的数据包的数量(而不仅仅是有和没有),所以可以更细粒度地进行拥塞控制。 以前做作业,问题和条件都是老师给出来的,顶多仔细读题,不存在去寻找可以利用的条件这个问题。我觉得很多时候,由知识储备不充分,或者对最新动向不了解,比如不知道现在各种路由器的功能,所以找不到更多的可以利用的条件。所以我觉得,要做好这一步,需要大量平时的积累,而不是仅仅靠脑子想就出结果了。 第三步就是把问题解决了。有了问题有了条件去解决问题,这一点在国内从小学就开始学了。所以我就不多说了。
5825 次阅读|1 个评论
CPU设计我要让更多的人掌握它(续3)
accsys 2010-1-4 03:22
2.2.2 组成存储设备的器件 计算机核心器件除了运算器之外,存储设备也是非常重要的组成部件。 2.2.2.1 触发器与寄存器 我们知道电信号传播的速度是同光的速度一样,300000km/s。因而电路输入端信号在输出端引起反应要经过一定的时间。可是电信号在一般电子器件中穿行的距离太小,因而许多小的电子器件电信号穿行的时间可以忽略不计。如果想让信号保留一段时间,必须用专门的设备,这种设备叫触发器,也称为锁存器。 一个触发器只能记录一位二进制数。如果将多个触发器组织在一起,并且能够人为地控制保存数据的时间,能够根据需要设置所保留的数据,这个设备就叫寄存器。 Verilog HDL语言将触发器看作寄存器的特例,用reg来描述寄存器。 例如,reg a,b;定义了一个16位的寄存器。对寄存器的赋值也简单用=或=符号进行。前者叫阻塞赋值,如果有多个这样的赋值表达式,要由前向后逐个进行。后者叫非阻塞赋值,多个这种赋值表达式可以同时进行。 例如,a = 8b10101000; b = 8b10000011; 要先给a赋值,然后再给b赋值。如果将此处的=换成=则a、b的赋值是同时进行的。赋值表达式的右侧是二进制常数10101000和10000011的表示,b是二进制表示符,单引号前面的数字是二进制数的位数。如果用其他进制表示数也可以,但前面的长度仍然用二进制的数码长度。 例如,a = 8b10101000;可以表示成 a = 8hA8;或a = 8o250;字母h代表十六进制,o代表八进制。 实际的电路并不像Verilog HDL语言书写的那样简单,而必需转化成能够完成置数和保存数的电路。 2.2.2.1.1 D型触发器 图 2 -6是一个D型触发器,能在CLK瞬间为1时让D的值在Q端保持。 图 2 -6 D型触发器 若CLK=1,则 S=D,R=D。如果此时D=1,那么S=1,R=0;由于门电路都是高电位起作用,所以或门再通过一个非门(或非门),使Q=0,于是瞬间形成Q=1,Q=0的状态。在CLK=1时,若D=0,那么S=0,R=1;由于或门电路高电位起作用,再通过一个非门,使Q=1,于是瞬间形成Q=0,Q=1的状态。可见不论D为何值,当CLK=1时,总有Q=D。 若此后CLK=0保持,则使S=R=0保持,但由于Q和Q的反馈作用和或非门的特点,Q=D的状态会一直保持,这是一个稳定的状态。 不难看出CLK=0的时间长短,决定着前面进入的D的值保持时间的长度。 2.2.2.1.2 前沿触发器 D型触发器通过CLK=1能够将D的值保持,但实际电路中D的值变化很快,快到CLK=1的时间段内,D的值发生多次变化,也就是我们得到的值不一定是我们所要的那个值。一个直接的想法是让CLK=1的时间非常短,短到D的值来不及变化的程度,还有一个办法是让某个时刻的D值保持不变。图 2- 7就是为了解决这个问题而设计的。 图 2 -7 前沿触发器及简图 图 2 7(a)中将两个D型触发器连接成一个前沿触发器。CLK=0时,通过一个非门的作用,使左面一个D型触发器不断将输入端D值传给其Q端输出,但右面的D型触发器由于CLK=0,故仍然保持原来的值。而当CLK由0变1的瞬间,通过图中的非门电路,左面一个D型触发器的外面输入被封锁,右面的D型触发器接收的输入就保持D被封锁前的最末的值。此后,不论CLK的值是否变成0,右面D型触发器的输出端总是前面那个CLK由0变1的瞬间的外界的那个D值。 由于CLK由0变1的瞬间是矩形波形的前沿,得到的D值就在 CLK的前沿,故称图 2- 7的触发器组合为前沿触发器。可知,前沿触发器能够准确地捕捉数据信号。 前沿触发器使用时用简单的图 2- 7(b)图形符号表示。 2.2.2.1.3 寄存器 将多个前沿触发器顺序排在一起,就组成了能够将多位数据保存在两个CLK=1的间隔时间内的寄存器。如果想控制保存的时间,只要在CLK线路上加一个与门电路,与门的一个输入端还是原来的CLK,这样用另一个输入端就可以控制所有的前沿触发器保存数据的时间。图 2 -8是寄存器的简图。 图 2 -8 寄存器 图 2 -8中斜线上方的数字表示多股线的条数。寄存器一般也用矩形来简单表示,将与门隐藏进矩形内,外面多标出一条控制线k。 2.2.2.2 计数器 用硬件程序设计语言解决寄存器加减运算是非常容易的事,因为只要定义了寄存器变量,就可以用加减运算符号表达出来。 计数器是能够作加一运算和减一运算的寄存器,它的动作要远比将寄存器的数送到运算器,做完加减一或减一之后再回送寄存器的速度快得多。 计数器的构造和工作原理,暂时不懂也不影响用Verilog HDL编写设计程序。如果读者想深入了解,请参考姜咏江写的《计算机原理教程》一书的120页至121页,或者参考《计算机原理综合课程设计》一书的82页。 --- 待续 ---
个人分类: 计算机核|4348 次阅读|0 个评论

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-6-17 08:44

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部