再学Python——多线程

Python多线程
进程

是程序的一次执行。每个进程都有自己的地址空间,内存,数据线及其它记录琪运行轨迹的辅助数据

线程

所有线程运行在同一个进程当中,共享相同的运行环境
每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制

多线程
多线程类似于同时执行多个不同程序

多线程运行有如下优点
①使用线程可以把占据长时间的程序中的任务放到后台去处理
②程序的运行速度可能加快
③在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,可以释放一些珍贵的资源如内存占用等等

Python 线程中常用的两个模块为
①thread
②threading(推荐使用)
thread 模块已被废弃。用户可以使用 threading 模块代替。

实验

看看以下实例,更容易理解哦

一、简单输出

start_new_thread(funtion,args kwargs=None)
产生一个线程,在新的线程中用指定的参数和可选的kwargs来调用这个函数。
注意:使用这个方法时,一定要加time.sleep(),否则线程可能不执行

import thread
import time

def func1():
        print 'Hello world %s\n'%time.ctime()

def main():
        thread.start_new_thread(func1,())
        thread.start_new_thread(func1,())
        thread.start_new_thread(func1,())
        thread.start_new_thread(func1,())
        //该线程同一时间执行
        time.sleep(2)

if __name__ == '__main__':        
        main()

在这里插入图片描述

二、利用系统ping对本地进行一个探测
import thread
import time
from subprocess import Popen,PIPE //调用系统用于直接执行系统命令

def func1():
        check = Popen('ping 127.0.0.1',shell=True,stdin=PIPE,stdout=PIPE)
        // Popen函数指定shell=True即可,linux下参数executable将指定程序使用的shell,windows下无须指定。
        data = check.stdout.read()
        //对返回包进行读取显示
        print data
        
func1()

在这里插入图片描述

三、在多线程基础上对内网c段进行一个扫描
import thread
import time
from subprocess import Popen,PIPE

def func1(ip):
        check = Popen('ping '+ ip,shell=True,stdin=PIPE,stdout=PIPE)
        data = check.stdout.read()
        //为了方便,利用TTL路由跳数对其进行判断是否存活/回显
        if 'TTL' in data:
                print '%s is up at %s'%(ip,time.ctime())
def main():
        for i in range(1,255):
                ip = "192.168.101."+str(i)
                thread.start_new_thread(func1,(ip,))
                //将ip形参传入func()
                time.sleep(0.1)
              
if __name__ == '__main__':        
        main()

在这里插入图片描述
(可以看到thread在多线程扫描时不受控制,并没有按顺序去扫描,而是通过“先收到先输出”的方式显示出来)

四、采用threading

threading模块 —— 解决了线程数可控的问题

import threading
import time
# from subprocess import Popen,PIPE

def func1(key):
        print 'Hello %s:%s\n'%(key,time.ctime())

def main():
        threads = []
        keys = ['zhangsan','lisi','123456']
        threads_count = len(keys) //数组长度 --- 线程数
        //将数组以线程形式返回给func1()
        for i in range(threads_count):
                thread = threading.Thread(target=func1,args=(keys[i],))
                //并且将线程添加到新的数组
                threads.append(thread)
        for i in range(threads_count):
                threads[i].start()
        for i in range(threads_count):
                threads[i].join()

if __name__ == '__main__':        
        main()

在这里插入图片描述

五、多线程访问某度(线程别太大,做个实例示范下而已)
import threading
import time
import requests
# from subprocess import Popen,PIPE

def func1():
        time_start = time.time()
        r = requests.get(url='http://www.baidu.com')
        times = time.time()-time_start 
        print ('Status:%s —— %s ——%s\n'%(r.status_code,times,time.ctime()))

def main():
        threads = []
        threads_count = 10 //调节线程数
        for i in range(threads_count):
                thread = threading.Thread(target=func1,args=())
                threads.append(thread)
        for i in range(threads_count):
                threads[i].start()
        for i in range(threads_count):
                threads[i].join()

if __name__ == '__main__':        
        main()

在这里插入图片描述

六、生产者-消费者问题和queue模块

—— 解决生产参数和计算结果时间都不确定的问题

queue模块的FIFO队列先进先出。LIFO类似于堆。即先进后出。还有一种是优先级队列级别越低越先出来。
针对这三种队列分别有三个构造函数
class Queue.Queue(maxsize) FIFO
class Queue.LifoQueue(maxsize) LIFO
class Queue.PriorityQueue(maxsize) 优先级队列

queue模块( qsize(),empty(),full(),put(),get() )
完美搭档,queue + threading

# -*- encoding:gbk -*-
import threading
import time
#import requests
from queue import Queue
from subprocess import Popen,PIPE

class DoRun(threading.Thread):
        def __init__(self,queue):
                threading.Thread.__init__(self)
                self._queue = queue 
        
        def run(self):
                while not self._queue.empty():
                        ip = self._queue.get() //从队列拿出ip
                        check = Popen('ping '+ ip,shell=True,stdin=PIPE,stdout=PIPE)
                        data = check.stdout.read()
						//坑!!因为用的python3,这里通过gbk对中文进行转码
                        data_str = str(data,'gbk')
                        if 'TTL' in data_str:
                                print ('%s is up at %s'%(ip,time.ctime()))

def main():
        threads = []
        threads_count = 10
        queue = Queue()
        for i in range(1,255):
                queue.put('192.168.101.'+str(i))  //将ip字符串添加到queue队列中
        for i in range(threads_count):
                threads.append(DoRun(queue))
        for i in threads:
                i.start()
        for i in threads:
                i.join()

if __name__ == '__main__':        
        main()

在这里插入图片描述 
GOT IT!

 
******************************************************
小实验小结,具体测试利用方式需根据具体实践场景~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值