线程,进程概念
分类:
IT文章
•
2023-11-04 10:42:44
当多个客户端访问服务端的时候,每个客户端都会对服务端说:’嗨,我想连接你‘。服务端的sorcket通过while循环,一直监听着是否有client请求连接,当有请求(一个或者多个)连接过来的时候:就会分配(一个或者多个)进程或者线程给client,并保持连接,进行通话。
线程是应用程序的最小单位,
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import threading
import time
def show(arg):
time.sleep(2)
print 'thread'+str(arg)
for i in range(10):
t = threading.Thread(target=show, args=(i,)) #这里实例化对象的时候传的两个参数第一个参数是,线程需要执行的方法,第二个参数方法的参数
t.start()
print 'main thread stop'
View Code
上述代码创建了10个“前台”线程,然后控制器就交给了CPU,CPU根据指定算法进行调度,分片执行指令。
再次回顾:这里为什么是分片执行?
python中的多线程,有一个GIL(Global Interpreter Lock 全局解释器锁 )在同一时间只有一个线程在工作,他底层会自动进行上下文切换.这个线程执行点,那个线程执行点!
更多方法:请自己多查看源码,多看,多看,看不懂,再看。
- start 线程准备就绪,等待CPU调度
- setName 为线程设置名称
- getName 获取线程名称
- setDaemon 设置为后台线程或前台线程(默认)
- 如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止
- 如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
- join 逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
- run 线程被cpu调度后执行Thread类对象的run方法
线程锁:
无线程锁:(多个线程同时对一个内存地址进行操作)
#!/sur/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'ganzl'
import threading
import time
gl_num = 0
def show(arg):
global gl_num
time.sleep(1)
gl_num +=1
print gl_num
for i in range(10):
t = threading.Thread(target=show, args=(i,))
t.start()
print 'main thread stop'
View Code
有线程锁:
#!/sur/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'ganzl'
import threading
import time
gl_num = 0
lock = threading.RLock() #实例化调用线程锁
def Func():
lock.acquire() #获取线程锁
global gl_num
gl_num +=1
time.sleep(1)
print gl_num
lock.release() #释放线程锁,这里注意,在使用线程锁的时候不能把锁,写在代码中,否则会造成阻塞,看起来“像”单线程
for i in range(10):
t = threading.Thread(target=Func)
t.start()
View Code
event
python线程的事件用于主线程控制其他子线程的控制。
事件主要提供了三个方法 set、wait、clear。
事件处理的机制:
全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,
如果“Flag”值为True,那么event.wait 方法时便不再阻塞。
- clear:将“Flag”设置为False
- set:将“Flag”设置为True
#!/sur/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'ganzl'
import threading
def do(event):
print 'start'
event.wait() #执行对象weit方法,然后他们停下来,等待“Flag”为True
print 'execute'
event_obj = threading.Event() #创建事件的对象
for i in range(2):
t = threading.Thread(target=do, args=(event_obj,)) #执行多线程。
t.start()
print dir(event_obj)
print event_obj.__dict__
print event_obj.__dict__['_Event__flag']
inp = raw_input('input:')
if inp == 'true':
event_obj.set()
print event_obj.__dict__['_Event__flag']
多进程:
注意:由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。
并且python不能再Windows下创建进程!(pycharm不能执行多线程的demo)
并且在使用多进程的时候,最好是创建多少个进程?:和CPU核数相等
Linux下,工作中用到的批量执行命令的demo:
#!/sur/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'ganzl'
import multiprocessing
import sys,os,time
import paramiko
def ssh_cmd(host,port,user,passwd,cmd):
msg = "-----------Result:%s----------" % host
s = paramiko.SSHClient()
s.load_system_host_keys()
s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
s.connect(host,22,user,passwd,timeout=5)
stdin,stdout,stderr = s.exec_command(cmd)
cmd_result = stdout.read(),stderr.read()
print msg
for line in cmd_result:
print line,
s.close()
except paramiko.AuthenticationException:
print msg
print 'AuthenticationException Failed'
except paramiko.BadHostKeyException:
print msg
print "Bad host key"
p = multiprocessing.Pool(processes=20)
#----------------等他与上面那一句
#from multiprocessing import Process,Pool
#p = Pool(20)
#----------------
cmd=raw_input('CMD:')
f=open('serverlist.conf')#当前目录下建立该配置文件,格式按照如下的方式
list = f.readlines()
f.close()
for IP in list:
host=IP.split()[0]
port=int(IP.split()[1])
user=IP.split()[2]
passwd=IP.split()[3]
p.apply_async(ssh_cmd,(host,port,user,passwd,cmd))#多进程执行的一个方法。
p.close()
p.join()
进程池
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,
如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。
进程池中有两个方法及demo:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from multiprocessing import Process,Pool
import time
def Foo(i):
time.sleep(2)
return i+100
def Bar(arg):
print arg
pool = Pool(5)
#print pool.apply(Foo,(1,))
#print pool.apply_async(func =Foo, args=(1,)).get()
for i in range(10):
pool.apply_async(func=Foo, args=(i,),callback=Bar)
print 'end'
pool.close()
pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
View Code
适用场景:其实在其他语言中,协程的其实是意义不大的多线程即可已解决I/O的问题,但是在python因为他有GIL(Global Interpreter Lock 全局解释器锁 )在同一时间只有一个线程在工作,所以:如果一个线程里面I/O操作特别多,协程就比较适用