【perl】threads多线程telnet批量管理网络设备

我的前一篇博文中已经讲过利用Coro协程模块编写批量telnet的脚本。最近我随“大溜”去了,自学python和C++(学会了perl,融会贯通,学习python是件挺轻松的事情)。多亏了python、C++中文材料丰富,尤其是多线程、并发这一块,让我进一步搞懂了一些概念。并且可以融汇贯通到perl中。

闲话少说,下面讲讲协程、多线程和进程的区别:

一般来说,协程属于线程,线程属于进程。

详细讲,就是操作系统调集内存、cpu等资源生成一个进程,也就是说进程拥有操作系统分配给他的固定的cpu、内存等资源。进程同样也可以调集这部分内存、cpu等资源进行细分,而细分出来的小块内存、cpu资源就是线程。

线程与进程相比,主要优势在于进程分配内存、CPU资源形成线程的速度要比操作系统分配内存、cpu等资源形成进程的速度要快,即线程的开销比进程的开销要小。

多线程开销小,但不代表没有开销,也就是说有进一步压缩开销的空间。于是,就出现了在一个线程中,通过“见缝插针”的方式,由程序自身的控制,在遇见线程堵塞时,将CPU让给其他要执行的任务。通过空闲时间内让出CPU资源,来模拟多线程,即为协程。

“协”,协商的意思。

无论是perl还是python,都是在单核上利用锁机制(也就是控制任务使用CPU的时间,实现多线程)的。

多线程和协程间的主要区别在于,谁来决定任务占用CPU资源的时间。

多线程,根据python的相关资料,我推断(相关书籍和材料,以及各大论坛上大牛的讲解,均没有明言的)是通过定时切换的,也可以说是固定频率的,每一个线程得到CPU资源的时间是相同的,依次轮流。可以说,多线程是自动的,不需要程序员去编写特定代码的。

协程,由程序员设计各个任务间如何切换CPU资源。也就是说,需要程序员自己利用特定的协程关键字去敲代码实现的,例如使用async/await、yield、cede等关键字。

所以,无论是perl的coro还是python的gevent以及3.5版本之后的async/await,要想用协程,程序员自己写的部分和导入的模块都必须实现协程。这就解释了,为什么Coro在CPAN可用的包很少,而python中gevent要重写标准库中网络包。

前面已经说了,对于多线程的机制,是我的推断。如果推断成立,CPAN上随便一个包,都可以通过多线程进行并发计算。而telnet批量管理网络设备,也就不用搞得像Coro那么复杂,直接用Net::Telnet模块就好了。当然,最后证明推断是没错的。

perl的多线程,历史较短,而且前期稳定性不高,所以在大小骆驼以及豹书等perl的主要中文书籍中都没有提及,加之anyevent、coro等模块备受推崇,所以perl自带的threads模块(注意thread是老模块,threads是官方推荐的用于替代thread。就像python中的threading一般)很容易被忽视。

其实,threads和python中的threading同样简单易用。

文章最后,放出多线程telnet的实现代码,内含同步代码(注释中已写明),可以自行比较:

use strict;
use threads;
use Thread::Semaphore;
use Net::Telnet::Cisco;

my $start = time();

my @host = ("192.168.0.2","192.168.0.3","192.168.0.4","192.168.0.5","192.168.0.6");

my @threads;
my $count = 0;

my $signal = Thread::Semaphore->new();                  #测试同步时,请注释掉此行

for my $host (@host) {
    $threads[$count] = threads->create(\&switch,$host); #测试同步时,请注释掉此行
    $count++;                                           #测试同步时,请注释掉此行
    #&switch($host); #测试同步时,请去掉注释!!!
}

for my $th (@threads) {                                 #测试同步时,请注释掉此行
    $th->join();                                        #测试同步时,请注释掉此行
}                                                       #测试同步时,请注释掉此行

my $endtime = time() - $start;
print "\n$endtime\n";

sub switch{
    my $host = shift;
    my $s = Net::Telnet::Cisco->new($host);
    $s->login(Name => 'cisco',Password => 'cisco');
    my @output = $s->cmd('show version');
    $signal->down();                                    #测试同步时,请注释掉此行
    print '*#*' x 30;
    print @output;
    print '=&=' x 30;
    $signal->up();                                      #测试同步时,请注释掉此行
    $s->close;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值