首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >多线程 VS 多进程(二)

多线程 VS 多进程(二)

原创
作者头像
ruochen
修改2021-05-11 14:39:09
修改2021-05-11 14:39:09
3810
举报
  • 共享变量
    • 共享变量:当多个线程同时访问同一个变量的时候,会产生共享变量的问题
    • 案例11 ```python import threading
代码语言:txt
复制
	sum = 0
代码语言:txt
复制
	loopSum = 1000000
代码语言:txt
复制
	def myAdd():
代码语言:txt
复制
	    global sum, loopSum
代码语言:txt
复制
	    for i in range(1, loopSum):
代码语言:txt
复制
	        sum += 1
代码语言:txt
复制
	def myMinu():
代码语言:txt
复制
	    global sum, loopSum
代码语言:txt
复制
	    for i in range(1, loopSum):
代码语言:txt
复制
	        sum -= 1
代码语言:txt
复制
	if __name__ == '__main__':
代码语言:txt
复制
	    print("Starting ....{0}".format(sum))
代码语言:txt
复制
	    # 开始多线程的实现,看执行结果是否一样
代码语言:txt
复制
	    t1 = threading.Thread(target=myAdd, args=())
代码语言:txt
复制
	    t2 = threading.Thread(target=myMinu, args=())
代码语言:txt
复制
	    t1.start()
代码语言:txt
复制
	    t2.start()
代码语言:txt
复制
	    t1.join()
代码语言:txt
复制
	    t2.join()
代码语言:txt
复制
	    print("Done ....{0}".format(sum))
代码语言:txt
复制
    ```
代码语言:txt
复制
    	Starting ....0
代码语言:txt
复制
		Done ....157577
代码语言:txt
复制
- 解决变量:锁,信号灯
- 锁(Lock):
    - 是一个标志,表示一个线程在占用一些资源
    - 使用方法
        - 上锁
        - 使用共享变量,放心的用
        - 取消锁,释放锁
    - 案例12
        ```python
    	import threading
		
代码语言:txt
复制
		sum = 0
代码语言:txt
复制
		loopSum = 1000000
代码语言:txt
复制
		lock = threading.Lock()
代码语言:txt
复制
		def myAdd():
代码语言:txt
复制
		    global  sum, loopSum
代码语言:txt
复制
		    for i in range(1, loopSum):
代码语言:txt
复制
		        # 上锁,申请锁
代码语言:txt
复制
		        lock.acquire()
代码语言:txt
复制
		        sum += 1
代码语言:txt
复制
		        # 释放锁
代码语言:txt
复制
		        lock.release()
代码语言:txt
复制
		def myMinu():
代码语言:txt
复制
		    global  sum, loopSum
代码语言:txt
复制
		    for i in range(1, loopSum):
代码语言:txt
复制
		        lock.acquire()
代码语言:txt
复制
		        sum -= 1
代码语言:txt
复制
		        lock.release()
代码语言:txt
复制
		if __name__ == '__main__':
代码语言:txt
复制
		    print("Starting ....{0}".format(sum))
代码语言:txt
复制
		    # 开始多线程的实现,看执行结果是否一样
代码语言:txt
复制
		    t1 = threading.Thread(target=myAdd, args=())
代码语言:txt
复制
		    t2 = threading.Thread(target=myMinu, args=())
代码语言:txt
复制
		    t1.start()
代码语言:txt
复制
		    t2.start()
代码语言:txt
复制
		    t1.join()
代码语言:txt
复制
		    t2.join()
代码语言:txt
复制
		    print("Done ....{0}".format(sum))
代码语言:txt
复制
        ```
代码语言:txt
复制
	        Starting ....0
代码语言:txt
复制
			Done ....0
代码语言:txt
复制
    - 锁谁:哪个资源需要多个线程共享,锁哪个
    - 理解锁:锁其实不是锁住谁,而是一个令牌
- 线程安全问题:
    - 如果一个资源/变量,他对于多线程来讲,不用加锁也不会引起任何问题,则称为线程安全
    - 线程不安全变量类型:list,set,dict
    - 线程安全变量类型:queue(队列)
- 生产者消费者问题
    - 一个模型,可以用来搭建消息队列
    - queue是一个用来存放变量的数据结构,特点是先进先出,内部元素排队,可以理解成一个特殊的list
    - 案例13
        ```python
        #encoding=utf-8
		import threading
		import time
		
代码语言:txt
复制
		# Python2
代码语言:txt
复制
		# from Queue import Queue
代码语言:txt
复制
		# Python3
代码语言:txt
复制
		import queue
代码语言:txt
复制
		class Producer(threading.Thread):
代码语言:txt
复制
		    def run(self):
代码语言:txt
复制
		        global queue
代码语言:txt
复制
		        count = 0
代码语言:txt
复制
		        while True:
代码语言:txt
复制
		            # qsize返回queue内容长度
代码语言:txt
复制
		            if queue.qsize() < 1000:
代码语言:txt
复制
		                for i in range(100):
代码语言:txt
复制
		                    count = count +1
代码语言:txt
复制
		                    msg = '生成产品'+str(count)
代码语言:txt
复制
		                    # put是往queue中放入一个值
代码语言:txt
复制
		                    queue.put(msg)
代码语言:txt
复制
		                    print(msg)
代码语言:txt
复制
		            time.sleep(0.5)
代码语言:txt
复制
		class Consumer(threading.Thread):
代码语言:txt
复制
		    def run(self):
代码语言:txt
复制
		        global queue
代码语言:txt
复制
		        while True:
代码语言:txt
复制
		            if queue.qsize() > 100:
代码语言:txt
复制
		                for i in range(3):
代码语言:txt
复制
		                    # get是从queue中取出一个值
代码语言:txt
复制
		                    msg = self.name + '消费了 '+queue.get()
代码语言:txt
复制
		                    print(msg)
代码语言:txt
复制
		            time.sleep(1)
代码语言:txt
复制
		if __name__ == '__main__':
代码语言:txt
复制
		    queue = queue.Queue()
代码语言:txt
复制
		    for i in range(500):
代码语言:txt
复制
		        queue.put('初始产品'+str(i))
代码语言:txt
复制
		    for i in range(2):
代码语言:txt
复制
		        p = Producer()
代码语言:txt
复制
		        p.start()
代码语言:txt
复制
		    for i in range(5):
代码语言:txt
复制
		        c = Consumer()
代码语言:txt
复制
		        c.start()
代码语言:txt
复制
        ```
代码语言:txt
复制
	        生成产品1
代码语言:txt
复制
			生成产品2
代码语言:txt
复制
			生成产品3
代码语言:txt
复制
			生成产品4
代码语言:txt
复制
			生成产品5
代码语言:txt
复制
			生成产品6
代码语言:txt
复制
			生成产品7
代码语言:txt
复制
			生成产品8
代码语言:txt
复制
			生成产品9
代码语言:txt
复制
			生成产品10
代码语言:txt
复制
			生成产品11
代码语言:txt
复制
			生成产品12
代码语言:txt
复制
			生成产品13
代码语言:txt
复制
			生成产品14
代码语言:txt
复制
			生成产品15
代码语言:txt
复制
			生成产品16
代码语言:txt
复制
			生成产品17
代码语言:txt
复制
			生成产品18生成产品1
代码语言:txt
复制
			生成产品2
代码语言:txt
复制
			生成产品3
代码语言:txt
复制
			生成产品4
代码语言:txt
复制
			生成产品5
代码语言:txt
复制
			生成产品6
代码语言:txt
复制
			生成产品7
代码语言:txt
复制
			生成产品8
代码语言:txt
复制
			生成产品9
代码语言:txt
复制
			生成产品10
代码语言:txt
复制
			生成产品11
代码语言:txt
复制
			生成产品19
代码语言:txt
复制
			生成产品12
代码语言:txt
复制
			生成产品13
代码语言:txt
复制
			生成产品14
代码语言:txt
复制
			生成产品20
代码语言:txt
复制
			生成产品21
代码语言:txt
复制
			生成产品22
代码语言:txt
复制
			生成产品23
代码语言:txt
复制
			生成产品24
代码语言:txt
复制
			生成产品25
代码语言:txt
复制
			生成产品26
代码语言:txt
复制
			生成产品15
代码语言:txt
复制
			生成产品16
代码语言:txt
复制
			生成产品17
代码语言:txt
复制
			生成产品18
代码语言:txt
复制
			生成产品19
代码语言:txt
复制
			生成产品20Thread-3消费了 初始产品0
代码语言:txt
复制
			Thread-3消费了 初始产品1
代码语言:txt
复制
			Thread-3消费了 初始产品2
代码语言:txt
复制
			生成产品27
代码语言:txt
复制
			Thread-4消费了 初始产品3
代码语言:txt
复制
			Thread-4消费了 初始产品4
代码语言:txt
复制
			Thread-4消费了 初始产品5
代码语言:txt
复制
			生成产品21生成产品28
代码语言:txt
复制
			生成产品29
代码语言:txt
复制
			生成产品30
代码语言:txt
复制
			生成产品31
代码语言:txt
复制
			生成产品32
代码语言:txt
复制
			生成产品33
代码语言:txt
复制
			生成产品34
代码语言:txt
复制
			生成产品22
代码语言:txt
复制
			生成产品23
代码语言:txt
复制
			生成产品24
代码语言:txt
复制
			生成产品25
代码语言:txt
复制
			生成产品26
代码语言:txt
复制
			生成产品27Thread-5消费了 初始产品6
代码语言:txt
复制
			Thread-5消费了 初始产品7
代码语言:txt
复制
			Thread-5消费了 初始产品8
代码语言:txt
复制
			...
代码语言:txt
复制
- 死锁问题,案例14
    ```python
    import threading
	import time
	
代码语言:txt
复制
	lock_1 = threading.Lock()
代码语言:txt
复制
	lock_2 = threading.Lock()
代码语言:txt
复制
	def func_1():
代码语言:txt
复制
	   print("func_1 starting.........")
代码语言:txt
复制
	   lock_1.acquire()
代码语言:txt
复制
	   print("func_1 申请了 lock_1....")
代码语言:txt
复制
	   time.sleep(2)
代码语言:txt
复制
	   print("func_1 等待 lock_2.......")
代码语言:txt
复制
	   lock_2.acquire()
代码语言:txt
复制
	   print("func_1 申请了 lock_2.......")
代码语言:txt
复制
	   lock_2.release()
代码语言:txt
复制
	   print("func_1 释放了 lock_2")
代码语言:txt
复制
	   lock_1.release()
代码语言:txt
复制
	   print("func_1 释放了 lock_1")
代码语言:txt
复制
	   print("func_1 done..........")
代码语言:txt
复制
	def func_2():
代码语言:txt
复制
	   print("func_2 starting.........")
代码语言:txt
复制
	   lock_2.acquire()
代码语言:txt
复制
	   print("func_2 申请了 lock_2....")
代码语言:txt
复制
	   time.sleep(4)
代码语言:txt
复制
	   print("func_2 等待 lock_1.......")
代码语言:txt
复制
	   lock_1.acquire()
代码语言:txt
复制
	   print("func_2 申请了 lock_1.......")
代码语言:txt
复制
	   lock_1.release()
代码语言:txt
复制
	   print("func_2 释放了 lock_1")
代码语言:txt
复制
	   lock_2.release()
代码语言:txt
复制
	   print("func_2 释放了 lock_2")
代码语言:txt
复制
	   print("func_2 done..........")
代码语言:txt
复制
	if __name__ == "__main__":
代码语言:txt
复制
	   print("主程序启动..............")
代码语言:txt
复制
	   t1 = threading.Thread(target=func_1, args=())
代码语言:txt
复制
	   t2 = threading.Thread(target=func_2, args=())
代码语言:txt
复制
	   t1.start()
代码语言:txt
复制
	   t2.start()
代码语言:txt
复制
	   t1.join()
代码语言:txt
复制
	   t2.join()
代码语言:txt
复制
	   print("主程序启动..............")
代码语言:txt
复制
    ```
代码语言:txt
复制
	    主程序启动..............
代码语言:txt
复制
		func_1 starting.........
代码语言:txt
复制
		func_1 申请了 lock_1....
代码语言:txt
复制
		func_2 starting.........
代码语言:txt
复制
		func_2 申请了 lock_2....
代码语言:txt
复制
		func_1 等待 lock_2.......
代码语言:txt
复制
		func_2 等待 lock_1.......
代码语言:txt
复制
- 锁的等待时间问题,案例15
    ```python
    import threading
	import time
	
代码语言:txt
复制
	lock_1 = threading.Lock()
代码语言:txt
复制
	lock_2 = threading.Lock()
代码语言:txt
复制
	def func_1():
代码语言:txt
复制
	    print("func_1 starting.........")
代码语言:txt
复制
	    lock_1.acquire(timeout=4)
代码语言:txt
复制
	    print("func_1 申请了 lock_1....")
代码语言:txt
复制
	    time.sleep(2)
代码语言:txt
复制
	    print("func_1 等待 lock_2.......")
代码语言:txt
复制
	    rst = lock_2.acquire(timeout=2)
代码语言:txt
复制
	    if rst:
代码语言:txt
复制
	        print("func_1 已经得到锁 lock_2")
代码语言:txt
复制
	        lock_2.release()
代码语言:txt
复制
	        print("func_1 释放了锁 lock_2")
代码语言:txt
复制
	    else:
代码语言:txt
复制
	        print("func_1 注定没申请到lock_2.....")
代码语言:txt
复制
	    lock_1.release()
代码语言:txt
复制
	    print("func_1 释放了 lock_1")
代码语言:txt
复制
	    print("func_1 done..........")
代码语言:txt
复制
	def func_2():
代码语言:txt
复制
	    print("func_2 starting.........")
代码语言:txt
复制
	    lock_2.acquire()
代码语言:txt
复制
	    print("func_2 申请了 lock_2....")
代码语言:txt
复制
	    time.sleep(4)
代码语言:txt
复制
	    print("func_2 等待 lock_1.......")
代码语言:txt
复制
	    lock_1.acquire()
代码语言:txt
复制
	    print("func_2 申请了 lock_1.......")
代码语言:txt
复制
	    lock_1.release()
代码语言:txt
复制
	    print("func_2 释放了 lock_1")
代码语言:txt
复制
	    lock_2.release()
代码语言:txt
复制
	    print("func_2 释放了 lock_2")
代码语言:txt
复制
	    print("func_2 done..........")
代码语言:txt
复制
	if __name__ == "__main__":
代码语言:txt
复制
	    print("主程序启动..............")
代码语言:txt
复制
	    t1 = threading.Thread(target=func_1, args=())
代码语言:txt
复制
	    t2 = threading.Thread(target=func_2, args=())
代码语言:txt
复制
	    t1.start()
代码语言:txt
复制
	    t2.start()
代码语言:txt
复制
	    t1.join()
代码语言:txt
复制
	    t2.join()
代码语言:txt
复制
	    print("主程序结束..............")
代码语言:txt
复制
    ```
代码语言:txt
复制
    	主程序启动..............
代码语言:txt
复制
		func_1 starting.........
代码语言:txt
复制
		func_1 申请了 lock_1....
代码语言:txt
复制
		func_2 starting.........
代码语言:txt
复制
		func_2 申请了 lock_2....
代码语言:txt
复制
		func_1 等待 lock_2.......
代码语言:txt
复制
		func_1 注定没申请到lock_2.....
代码语言:txt
复制
		func_1 释放了 lock_1
代码语言:txt
复制
		func_2 等待 lock_1.......
代码语言:txt
复制
		func_1 done..........
代码语言:txt
复制
		func_2 申请了 lock_1.......
代码语言:txt
复制
		func_2 释放了 lock_1
代码语言:txt
复制
		func_2 释放了 lock_2
代码语言:txt
复制
		func_2 done..........
代码语言:txt
复制
		主程序结束..............
代码语言:txt
复制
- semphore
    - 允许一个资源对多有几个多线程同时使用
    - 案例16
        ```python
        import threading
		import time
		
代码语言:txt
复制
		# 参数定义最多几个线程同时使用资源
代码语言:txt
复制
		semaphore = threading.Semaphore(3)
代码语言:txt
复制
		def func():
代码语言:txt
复制
		    if semaphore.acquire():
代码语言:txt
复制
		        for i in range(5):
代码语言:txt
复制
		            print(threading.currentThread().getName() + 'get semaphore')
代码语言:txt
复制
		        time.sleep(15)
代码语言:txt
复制
		        semaphore.release()
代码语言:txt
复制
		        print(threading.currentThread().getName() + 'release semaphore')
代码语言:txt
复制
		for i in range(8):
代码语言:txt
复制
		    t1 = threading.Thread(target=func)
代码语言:txt
复制
		    t1.start()
代码语言:txt
复制
        ```
代码语言:txt
复制
	        Thread-1get semaphore
代码语言:txt
复制
			Thread-1get semaphore
代码语言:txt
复制
			Thread-1get semaphore
代码语言:txt
复制
			Thread-1get semaphore
代码语言:txt
复制
			Thread-1get semaphore
代码语言:txt
复制
			Thread-2get semaphore
代码语言:txt
复制
			Thread-2get semaphore
代码语言:txt
复制
			Thread-2get semaphore
代码语言:txt
复制
			Thread-2get semaphore
代码语言:txt
复制
			Thread-2get semaphore
代码语言:txt
复制
			Thread-3get semaphore
代码语言:txt
复制
			Thread-3get semaphore
代码语言:txt
复制
			Thread-3get semaphore
代码语言:txt
复制
			Thread-3get semaphore
代码语言:txt
复制
			Thread-3get semaphore
代码语言:txt
复制
			Thread-2release semaphoreThread-1release semaphore
代码语言:txt
复制
			Thread-5get semaphore
代码语言:txt
复制
			Thread-5get semaphore
代码语言:txt
复制
			Thread-5get semaphore
代码语言:txt
复制
			Thread-5get semaphore
代码语言:txt
复制
			Thread-5get semaphore
代码语言:txt
复制
			Thread-4get semaphore
代码语言:txt
复制
			Thread-4get semaphore
代码语言:txt
复制
			Thread-4get semaphore
代码语言:txt
复制
			Thread-4get semaphore
代码语言:txt
复制
			Thread-4get semaphore
代码语言:txt
复制
			Thread-3release semaphoreThread-6get semaphore
代码语言:txt
复制
			Thread-6get semaphore
代码语言:txt
复制
			Thread-6get semaphore
代码语言:txt
复制
			Thread-6get semaphore
代码语言:txt
复制
			Thread-6get semaphore
代码语言:txt
复制
			...
代码语言:txt
复制
- threading.Timer
    - 案例17
        ```python
        import threading
		import time
		
代码语言:txt
复制
		def func():
代码语言:txt
复制
		    print("I am running.........")
代码语言:txt
复制
		    time.sleep(4)
代码语言:txt
复制
		    print("I am done...")
代码语言:txt
复制
		if __name__ == "__main__":
代码语言:txt
复制
		    t = threading.Timer(6, func)
代码语言:txt
复制
		    t.start()
代码语言:txt
复制
		    i = 0
代码语言:txt
复制
		    while True:
代码语言:txt
复制
		        print("{0}*****************".format(i))
代码语言:txt
复制
		        time.sleep(3)
代码语言:txt
复制
		        i += 1
代码语言:txt
复制
        ```
代码语言:txt
复制
	        0*****************
代码语言:txt
复制
			1*****************
代码语言:txt
复制
			I am running.........
代码语言:txt
复制
			2*****************
代码语言:txt
复制
			3*****************
代码语言:txt
复制
			I am done...
代码语言:txt
复制
			4*****************
代码语言:txt
复制
			5*****************
代码语言:txt
复制
			6*****************
代码语言:txt
复制
			7*****************
代码语言:txt
复制
			8*****************
代码语言:txt
复制
			...
代码语言:txt
复制
    - Timer是利用多线程,在指定时间后启动一个功能
- 可重入锁
    - 一个锁,可以被一个线程多次申请
    - 主要解决递归调用的时候,需要申请锁的情况
    - 案例18
        ```python
        import threading
		import time
		
代码语言:txt
复制
		class MyThread(threading.Thread):
代码语言:txt
复制
		    def run(self):
代码语言:txt
复制
		        global num
代码语言:txt
复制
		        time.sleep(1)
代码语言:txt
复制
		        if mutex.acquire(1):
代码语言:txt
复制
		            num = num+1
代码语言:txt
复制
		            msg = self.name+' set num to '+str(num)
代码语言:txt
复制
		            print(msg)
代码语言:txt
复制
		            mutex.acquire()
代码语言:txt
复制
		            mutex.release()
代码语言:txt
复制
		            mutex.release()
代码语言:txt
复制
		num = 0
代码语言:txt
复制
		mutex = threading.RLock()
代码语言:txt
复制
		def testTh():
代码语言:txt
复制
		    for i in range(5):
代码语言:txt
复制
		        t = MyThread()
代码语言:txt
复制
		        t.start()
代码语言:txt
复制
		if __name__ == "__main__":
代码语言:txt
复制
		    testTh()
代码语言:txt
复制
        ```
代码语言:txt
复制
	        Thread-1 set num to 1
代码语言:txt
复制
			Thread-3 set num to 2
代码语言:txt
复制
			Thread-2 set num to 3
代码语言:txt
复制
			Thread-4 set num to 4
代码语言:txt
复制
			Thread-5 set num to 5

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档