*****Python之进程线程*****

Python之进程线程

  Python的threading模块

    并发编程:

    操作系统:位于底层硬件与应用软件之间的一层。

    工作方式:向下管理硬件,向上提供接口。

 

  进程:资源管理单位(容器)

  线程:最小执行单位

  Python的多线程:由于GIL,导致同一时间,同一时刻,只能有一个线程在运行。

  t.join():线程对象t未执行完,会阻塞你的主线程。

  

  全局解释器锁GIL:加在CPython解释器上。

  计算密集型:一直在使用CPU

  IO:存在大量的IO操作

 

  总结:

    对于计算密集型任务:Python的多线程没用

    对于IO密集型任务:Python的多线程有用

 

  Python使用多核:开进程,

        弊端:开销大,切换复杂

 

    重点:协程+多进程

      IO多路复用

  线程:  

 1 #  调用方式1
 2 
 3 # import threading
 4 # import time
 5 #
 6 # def tingge():
 7 #     print("听歌")
 8 #     time.sleep(3)
 9 #     print("听歌结束")
10 #
11 # def xieboke():
12 #     print("写博客")
13 #     time.sleep(5)
14 #     print("写博客结束")
15 #
16 #     print(time.time()-s)
17 #
18 # s=time.time()
19 #
20 # t1=threading.Thread(target=tingge)
21 # t2=threading.Thread(target=xieboke)
22 #
23 # t1.start()
24 # t2.start()
25 
26 
27 
28 #  调用方式2
29 # import threading
30 # import time
31 #
32 # class MyThread(threading.Thread):
33 #
34 #     def __init__(self,num):
35 #         threading.Thread.__init__(self)
36 #         self.num=num
37 #
38 #     def run(self):
39 #         print("running on number:%s" %self.num)
40 #         time.sleep(3)
41 
42 # t1=MyThread(56)
43 # t2=MyThread(78)
44 #
45 # t1.start()
46 # t2.start()
47 #
48 # print("ending")
View Code

  

 1 import threading
 2 from time import ctime,sleep
 3 import time
 4 
 5 def Music(name):
 6 
 7         print ("Begin listening to {name}. {time}".format(name=name,time=ctime()))
 8         sleep(3)
 9         print(threading.activeCount())
10         print(threading.enumerate())
11         print("end listening {time}".format(time=ctime()))
12 
13 
14 def Blog(title):
15 
16         print ("Begin recording the {title}. {time}".format(title=title,time=ctime()))
17         sleep(5)
18         print('end recording {time}'.format(time=ctime()))
19 
20 
21 threads = []
22 
23 
24 t1 = threading.Thread(target=Music,args=('FILL ME',),name="sub_thread")
25 t2 = threading.Thread(target=Blog,args=('',))
26 
27 threads.append(t1)
28 threads.append(t2)
29 
30 if __name__ == '__main__':
31 
32     t1.setDaemon(True)  # daemon:监听
33 
34     for t in threads:
35 
36         t.start()
37 
38     print ("all over %s" %ctime())
View Code

 

  GIL锁:

 1 import time
 2 
 3 
 4 def cal(n):
 5     sum=0
 6     for i in range(n):
 7        sum += i
 8 
 9 s=time.time()
10 
11 import threading
12 
13 
14 t1=threading.Thread(target=cal,args=(50000000,))
15 t2=threading.Thread(target=cal,args=(50000000,))
16 
17 t1.start()
18 t2.start()
19 t1.join()
20 t2.join()
21 
22 # cal(50000000)
23 # cal(50000000)
24 
25 print("time",time.time()-s)
View Code

 

  JOIN和Daemon:

 1 # import threading
 2 # from time import ctime,sleep
 3 # import time
 4 #
 5 # def Music(name):
 6 #
 7 #         print ("Begin listening to {name}. {time}".format(name=name,time=ctime()))
 8 #         sleep(3)
 9 #         print("end listening {time}".format(time=ctime()))
10 #
11 # def Blog(title):
12 #
13 #         print ("Begin recording the {title}. {time}".format(title=title,time=ctime()))
14 #         sleep(5)
15 #         print('end recording {time}'.format(time=ctime()))
16 #
17 #
18 # threads = []
19 #
20 # t1 = threading.Thread(target=Music,args=('FILL ME',))
21 # t2 = threading.Thread(target=Blog,args=('python',))
22 #
23 # threads.append(t1)
24 # threads.append(t2)
25 #
26 # if __name__ == '__main__':
27 
28     #t2.setDaemon(True)
29     # t2.setDaemon(True)
30 
31     # for t in threads:
32     #
33     #     t.start()
34 
35     # for t in threads:
36     #     t.join()
37 
38     # t1.start()
39     # t1.join()
40     # t2.start()
41     # t2.join()
42 
43     # print ("all over %s" %ctime())
View Code

 

  死锁和递归锁(RLock):

  RLock内部维护里一个计数器,与同步锁相比,可以多次release和acquire。  加锁是维护公共数据。

 1 import threading
 2 import time
 3 
 4 # mutexA = threading.Lock()
 5 # mutexB = threading.Lock()
 6 
 7 Rlock=threading.RLock()
 8 
 9 class MyThread(threading.Thread):
10 
11     def __init__(self):
12         threading.Thread.__init__(self)
13 
14     def run(self):
15 
16         self.fun1()
17         self.fun2()
18 
19     def fun1(self):
20 
21         Rlock.acquire()  # 如果锁被占用,则阻塞在这里,等待锁的释放
22 
23         print ("I am %s , get res: %s---%s" %(self.name, "ResA",time.time()))
24 
25         Rlock.acquire()  # count=2
26         print ("I am %s , get res: %s---%s" %(self.name, "ResB",time.time()))
27         Rlock.release()   #count-1
28 
29         Rlock.release()   #count-1 =0
30 
31 
32     def fun2(self):
33         Rlock.acquire()  # count=1
34         print ("I am %s , get res: %s---%s" %(self.name, "ResB",time.time()))
35         time.sleep(0.2)
36 
37         Rlock.acquire()  # count=2
38         print ("I am %s , get res: %s---%s" %(self.name, "ResA",time.time()))
39         Rlock.release()
40 
41         Rlock.release()   # count=0
42 
43 
44 if __name__ == "__main__":
45 
46     print("start---------------------------%s"%time.time())
47 
48     for i in range(0, 10):
49 
50         my_thread = MyThread()
51         my_thread.start()
View Code

 

  同步锁:  

 1 import time
 2 import threading
 3 
 4 def subNum():
 5 
 6     global num #在每个线程中都获取这个全局变量
 7     # num-=1
 8     print("ok")
 9     lock.acquire()   #上锁
10     temp=num
11     time.sleep(0.1)
12     num =temp-1  # 对此公共变量进行-1操作
13     lock.release()  #解锁
14 
15 num = 100  #设定一个共享变量
16 thread_list = []
17 
18 lock=threading.Lock()
19 
20 for i in range(100):
21     t = threading.Thread(target=subNum)
22     t.start()
23     thread_list.append(t)
24     # t.join()
25 
26 for t in thread_list: #等待所有线程执行完毕
27     t.join()
28 
29 print('Result: ', num)
View Code

 

  反射: 

 1 # #继承Thread式创建
 2 #
 3 # import threading
 4 # import time
 5 #
 6 # class MyThread(threading.Thread):
 7 #
 8 #     def __init__(self,num):
 9 #         threading.Thread.__init__(self)
10 #         self.num=num
11 #
12 #     def run(self):
13 #         print("running on number:%s" %self.num)
14 #         time.sleep(3)
15 #
16 # t1=MyThread(56)
17 # t2=MyThread(78)
18 #
19 # t1.start()
20 # t2.start()
21 # print("ending")
22 import time
23 class Card:
24     bank="工行"
25     def __init__(self,card_number,own_name,money,card_date):
26         self.card_number=card_number
27         self.own_name=own_name
28         self.money=money
29         self.card_date=card_date
30     def view(self):
31         print("账户信息,%s欢迎登录"%(self.bank),self.card_number,self.own_name,self.money,self.card_date)
32     def take(self,take_money):
33         mum=self.money-take_money
34         print("你一共取了%s,余额为%s",take_money,mum)
35 
36 c1=Card("6220144549585","lzh",10000,time.asctime())
37 # print(c1.__dict__)#为什么我们可以用字符串操作类下的数据属性和函数属性,因为它们都是以字典的形式存在
38 print(hasattr(c1,"bank"))#hasattr,以字符串的形式获取类下的属性名,如果存在返回真
39 print(getattr(c1,"take"))#getattr,得到类下的一个函数属性,如果存在返回一个绑定的函数方法
40 print(getattr(c1,"take1","没有这个方法"))#getattr,如果没有指定的属性,则报错,getattr还可以添加一个自定义的报错值
41 #当添加这个值后,getattr方法会返回这个定义值
42 setattr(c1,"addr","沙河分行")#该方法添加类的数据属性
43 setattr(c1,"bank","爱存不存")#此处可以修改类中的数据属性值
44 print(c1.bank)
45 print(c1.addr)
46 delattr(c1,"bank")
47 print(c1.__dict__)
48 #简单的应用示例,我们可以通过用户输入字符串的形式确定类这个对象中是否有这个操作,
49 # 如果有,就执行,显示结果,没有就不做任何操作
50 if hasattr(c1,"view"):
51     func=getattr(c1,"view")
52     res=func()
53     print(res)
54 else:
55     pass
View Code

 

  event对象:理解为标识位,True和False就好。False将阻塞线程。用set方法,event.set()将event的False状态改为True。

 

 

 

 1 import threading
 2 import time
 3 import logging
 4 
 5 logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s) %(message)s',)
 6 
 7 
 8 def worker(event):
 9     logging.debug('Waiting for redis ready...')
10 
11     while not event.isSet():
12         logging.debug("wait.......")
13         event.wait(3)   # if flag=False阻塞,等待flag=true继续执行
14 
15 
16     logging.debug('redis ready, and connect to redis server and do some work [%s]', time.ctime())
17     time.sleep(1)
18 
19 def main():
20 
21     readis_ready = threading.Event()  #  flag=False
22     t1 = threading.Thread(target=worker, args=(readis_ready,), name='t1')
23     t1.start()
24 
25     t2 = threading.Thread(target=worker, args=(readis_ready,), name='t2')
26     t2.start()
27 
28     logging.debug('first of all, check redis server, make sure it is OK, and then trigger the redis ready event')
29 
30     time.sleep(6) # simulate the check progress
31     readis_ready.set()  # flag=Ture
32 
33 
34 if __name__=="__main__":
35     main()
View Code

 

  信号量: 

 1 import threading
 2 import time
 3 
 4 semaphore = threading.Semaphore(5)
 5 
 6 def func():
 7 
 8     semaphore.acquire()
 9     print (threading.currentThread().getName() + ' get semaphore')
10     time.sleep(2)
11     semaphore.release()
12 
13 
14 for i in range(20):
15   t1 = threading.Thread(target=func)
16   t1.start()
View Code

 

   进程模块:multiprocessing

 1 #coding:utf8
 2 from multiprocessing import Process
 3 import time
 4 
 5 def counter():
 6     i = 0
 7     for _ in range(40000000):
 8         i = i + 1
 9 
10     return True
11 
12 def main():
13 
14     l=[]
15     start_time = time.time()
16     #
17     # for _ in range(2):
18     #     t=Process(target=counter)
19     #     t.start()
20     #     l.append(t)
21     #     #t.join()
22     #
23     # for t in l:
24     #    t.join()
25 
26     # counter()
27     # counter()
28 
29     end_time = time.time()
30     print("Total time: {}".format(end_time - start_time))
31 
32 if __name__ == '__main__':
33 
34     main()
View Code
 1 # from multiprocessing import Process
 2 #
 3 #
 4 # import time
 5 #
 6 #
 7 # def f(name):
 8 #
 9 #     print('hello', name,time.ctime())
10 #     time.sleep(1)
11 #
12 # if __name__ == '__main__':
13 #     p_list=[]
14 #
15 #     for i in range(3):
16 #         p = Process(target=f, args=('alvin:%s'%i,))
17 #         p_list.append(p)
18 #         p.start()
19 #
20 #
21 #     # for i in p_list:
22 #     #     p.join()
23 #
24 #     print('end')
View Code
 1 from multiprocessing import Process
 2 import os
 3 import time
 4 
 5 def info(name):
 6 
 7     print("name:",name)
 8     print('parent process:', os.getppid())
 9     print('process id:', os.getpid())
10     print("------------------")
11 
12 
13 def foo(name):
14 
15     info(name)
16     time.sleep(50)
17 
18 if __name__ == '__main__':
19 
20     info('main process line')
21 
22 
23     p1 = Process(target=info, args=('alvin',))
24     p2 = Process(target=foo, args=('egon',))
25     p1.start()
26     p2.start()
27 
28     p1.join()
29     p2.join()
30 
31     print("ending")
32     time.sleep(100)
View Code

 

  协程:  

    协程的优点,由于单线程,所以就不用再切换。

    不在有锁的概念。

 1 import time
 2 
 3 #  可以实现并发
 4 
 5 
 6 def consumer():
 7 
 8     r = ''
 9     while True:
10 
11         n = yield r
12         if not n:
13             return
14         print('[CONSUMER] ←← Consuming %s...' % n)
15         time.sleep(1)
16         r = '200 OK'
17 
18 def produce(c):
19 
20     next(c)
21     n = 0
22     while n < 5:
23         n = n + 1
24         print('[PRODUCER] →→ Producing %s...' % n)
25 
26         cr = c.send(n)
27 
28         print('[PRODUCER] Consumer return: %s' % cr)
29 
30     c.close()
31 
32 if __name__=='__main__':
33 
34     c = consumer()
35     produce(c)
View Code

 

  greenlet模块:

 1 # from greenlet import greenlet
 2 #
 3 #
 4 # def test1():
 5 #     print(12)
 6 #
 7 #     gr2.switch()
 8 #     print(34)
 9 #     gr2.switch()
10 #
11 #
12 # def test2():
13 #     print(56)
14 #     gr1.switch()
15 #     print(78)
16 #
17 #
18 # gr1 = greenlet(test1)
19 # gr2 = greenlet(test2)
20 #
21 # gr1.switch()
22 
23 
24 #gevent模块
25 
26 # import gevent
27 # import time
28 #
29 # def foo():
30 #     print("running in foo")
31 #     gevent.sleep(2)
32 #     print("switch to foo again")
33 #
34 # def bar():
35 #     print("switch to bar")
36 #     gevent.sleep(5)
37 #     print("switch to bar again")
38 #
39 # start=time.time()
40 #
41 # gevent.joinall(
42 #     [gevent.spawn(foo),
43 #     gevent.spawn(bar)]
44 # )
45 #
46 # print(time.time()-start)
47 
48 from gevent import monkey
49 monkey.patch_all()
50 
51 import gevent
52 from urllib import request
53 import time
54 
55 def f(url):
56     print('GET: %s' % url)
57     resp = request.urlopen(url)
58     data = resp.read()
59     print('%d bytes received from %s.' % (len(data), url))
60 
61 start=time.time()
62 
63 # gevent.joinall([
64 #         gevent.spawn(f, 'https://itk.org/'),
65 #         gevent.spawn(f, 'https://www.github.com/'),
66 #         gevent.spawn(f, 'https://zhihu.com/'),
67 # ])
68 
69 f('https://itk.org/')
70 f('https://www.github.com/')
71 f('https://zhihu.com/')
72 
73 
74 print(time.time()-start)
View Code

 

  test:  

 1 # class A:
 2 #     def __fa(self):
 3 #         print('from A')
 4 #     def test(self):
 5 #         self.__fa() #_A__fa
 6 #
 7 # class B(A):
 8 #     def __fa(self):
 9 #         print('from B')
10 #
11 # b=B()
12 # b.test()
13 
14 
15 
16 
17 #用来计算类被实例化的次数
18 # def get_no_(cls_obj):
19 #     return cls_obj.times_inst
20 #通常情况下,类实例是解释器自动调用类的__init__()来构造的,通常情况下,类实例是解释器自动调用类的__init__()来构造的
21 class Exm_cls:
22     #实例化次数的初始值为0
23     times_inst = 0
24     #类被实例化一次,就+1
25     def __init__(self):
26         Exm_cls.times_inst +=1
27     #在内部定义这个函数,并且把他绑定到类
28     @classmethod
29     def get_no_(cls):
30         return cls.times_inst
31     @staticmethod
32     def show_type():
33         fn = classmethod(Exm_cls.get_no_)
34         print(type(fn))
35 exm1 = Exm_cls()
36 exm2 = Exm_cls()
37 print(Exm_cls.get_no_())
38 print(Exm_cls.show_type())
39 # print(get_no_(Exm_cls))
View Code

 

 

链接

 

posted @ 2018-07-25 18:40  王先生是胖子  阅读(233)  评论(0编辑  收藏  举报