怎么样在python多线程实现检测服务器

Python016

怎么样在python多线程实现检测服务器,第1张

需要ping一个网段所有机器的在线情况,shell脚步运行时间太长,用python写个多线程ping吧,代码如下:

#!/usr/bin/python

#coding=utf-8

'''

Created on 2015-8-4

@author: Administrator

'''

import threading,subprocess

from time import ctime,sleep,time

import Queue

queue=Queue.Queue()

class ThreadUrl(threading.Thread):

def __init__(self,queue):

threading.Thread.__init__(self)

self.queue=queue

def run(self):

while True:

host=self.queue.get()

ret=subprocess.call('ping -c 1 -w 1 '+host,shell=True,stdout=open('/dev/null','w'))

if ret:

print "%s is down" % host

else:

print "%s is up" % host

self.queue.task_done()

def main():

for i in range(100):

t=ThreadUrl(queue)

t.setDaemon(True)

t.start()

for host in b:

queue.put(host)

queue.join()

a=[]

with open('ip.txt') as f:

for line in f.readlines():

a.append(line.split()[0])

#print a

b=['192.168.3.'+str(x) for x in range(1,254)] #ping 192.168.3 网段

start=time()

main()

print "Elasped Time:%s" % (time()-start)

#t2=threading.Thread(target=move,args=('fff',))

#threads.append(t2)

'''

for i in a:

print ctime()

ping(i)

sleep(1)

if __name__ == '__main__':

for t in range(len(a)):

#t.setDaemon(True)

threads[t].start()

#t.join()

print "All over %s" % ctime()

'''

线程在程序中是独立的、并发的执行流。与分隔的进程相比,进程中线程之间的隔离程度要小,它们共享内存、文件句柄和其他进程应有的状态。

因为线程的划分尺度小于进程,使得多线程程序的并发性高。进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

线程比进程具有更高的性能,这是由于同一个进程中的线程都有共性多个线程共享同一个进程的虚拟空间。线程共享的环境包括进程代码段、进程的公有数据等,利用这些共享的数据,线程之间很容易实现通信。

操作系统在创建进程时,必须为该进程分配独立的内存空间,并分配大量的相关资源,但创建线程则简单得多。因此,使用多线程来实现并发比使用多进程的性能要高得多。

总结起来,使用多线程编程具有如下几个优点:

进程之间不能共享内存,但线程之间共享内存非常容易。

操作系统在创建进程时,需要为该进程重新分配系统资源,但创建线程的代价则小得多。因此,使用多线程来实现多任务并发执行比使用多进程的效率高。

Python 语言内置了多线程功能支持,而不是单纯地作为底层操作系统的调度方式,从而简化了 Python 的多线程编程。

在实际应用中,多线程是非常有用的。比如一个浏览器必须能同时下载多张图片;一个 Web 服务器必须能同时响应多个用户请求;图形用户界面(GUI)应用也需要启动单独的线程,从主机环境中收集用户界面事件……总之,多线程在实际编程中的应用是非常广泛的。

进程的概念:以一个整体的形式暴露给操作系统管理,里面包含各种资源的调用。 对各种资源管理的集合就可以称为进程。

线程的概念:是操作系统能够进行运算调度的最小单位。本质上就是一串指令的集合。

进程和线程的区别:

1、线程共享内存空间,进程有独立的内存空间。

2、线程启动速度快,进程启动速度慢。注意:二者的运行速度是无法比较的。

3、线程是执行的指令集,进程是资源的集合

4、两个子进程之间数据不共享,完全独立。同一个进程下的线程共享同一份数据。

5、创建新的线程很简单,创建新的进程需要对他的父进程进行一次克隆。

6、一个线程可以操作(控制)同一进程里的其他线程,但是进程只能操作子进程

7、同一个进程的线程可以直接交流,两个进程想要通信,必须通过一个中间代理来实现。

8、对于线程的修改,可能会影响到其他线程的行为。但是对于父进程的修改不会影响到子进程。

第一个程序,使用循环来创建线程,但是这个程序中一共有51个线程,我们创建了50个线程,但是还有一个程序本身的线程,是主线程。这51个线程是并行的。注意:这个程序中是主线程启动了子线程。

相比上个程序,这个程序多了一步计算时间,但是我们观察结果会发现,程序显示的执行时间只有0.007秒,这是因为最后一个print函数它存在于主线程,而整个程序主线程和所有子线程是并行的,那么可想而知,在子线程还没有执行完毕的时候print函数就已经执行了,总的来说,这个时间只是执行了一个线程也就是主线程所用的时间。

接下来这个程序,吸取了上面这个程序的缺点,创建了一个列表,把所有的线程实例都存进去,然后使用一个for循环依次对线程实例调用join方法,这样就可以使得主线程等待所创建的所有子线程执行完毕才能往下走。 注意实验结果:和两个线程的结果都是两秒多一点

注意观察实验结果,并没有执行打印task has done,并且程序执行时间极其短。

这是因为在主线程启动子线程前把子线程设置为守护线程。

只要主线程执行完毕,不管子线程是否执行完毕,就结束。但是会等待非守护线程执行完毕

主线程退出,守护线程全部强制退出。皇帝死了,仆人也跟着殉葬

应用的场景 : socket-server

注意:gil只是为了减低程序开发复杂度。但是在2.几的版本上,需要加用户态的锁(gil的缺陷)而在3点几的版本上,加锁不加锁都一样。

下面这个程序是一个典型的生产者消费者模型。

生产者消费者模型是经典的在开发架构中使用的模型

运维中的集群就是生产者消费者模型,生活中很多都是

那么,多线程的使用场景是什么?

python中的多线程实质上是对上下文的不断切换,可以说是假的多线程。而我们知道,io操作不占用cpu,计算占用cpu,那么python的多线程适合io操作密集的任务,比如socket-server,那么cpu密集型的任务,python怎么处理?python可以折中的利用计算机的多核:启动八个进程,每个进程有一个线程。这样就可以利用多进程解决多核问题。