<strong>多进程补充</strong><br></br>joinable Queue<br></br><br></br>q=JoinableQueue<br></br>q.put(1)<br></br>q.put(2)<br></br>print(q.get())<br></br>q.task_done() <strong>告诉容器已经处理完成了一个数据 有几个数据就要调用几次</strong><br></br>q.task_done()<br></br><br></br>q.join() <strong>也是一个阻塞函数 一直到队列中的数据被处理完毕(task_done的调用次数等于队列中的数据数量)</strong><br></br>print('处理完成')<br></br><br></br>

多进程(补充),多线程,锁教程多进程(补充),多线程,锁教程

# from multiprocessing import  Process,Queue,JoinableQueue
# import time,random
#
# # 生产者
# def make_hot_dog(q):
#     for i in range(1,6):
#         time.sleep(random.randint(1,3))
#         print("\033[46m生产者 生产了hot_dog%s\033[0m" % i)
#         q.put("hot_dog%s" % i)
# # 消费者
# def eat_hot_dog(q):
#     while True:
#         time.sleep(random.randint(1, 2))
#         hot_dog = q.get()
#         print("思聪吃了%s" % hot_dog)
#         q.task_done()
#
#
# if __name__ == '__main__':
#     # 共享数据的队列
#     q = JoinableQueue()
#
#     # 生产者
#     p1 = Process(target=make_hot_dog,args=(q,))
#     p2 = Process(target=make_hot_dog,args=(q,))
#     p1.start()
#     p2.start()
#
#
#     # 消费者
#     c1 = Process(target=eat_hot_dog,args=(q,))
#     c1.daemon = True
#     c1.start()
#
#     # print("完成了吗???")
#     #先要确定生产者已经不会再生产了
#     p1.join()
#     p2.join()
#
#     print("生产已经结束了...")
#     #再确定队列中的所有数据都被处理完成
#     q.join()
#     print("思聪已经全部吃完了....")
#
#
#     # c1.terminate()
#     #王思聪就不需要在吃了

生产者消费者模型

<br></br><br></br><br></br>进程池<br></br>1.多线程理论(重点)<br></br>2.多线程使用方法(重点)<br></br>    两种创建方式<br></br>    常用属性<br></br>锁<br></br>互斥锁<br></br>死锁<br></br><br></br><br></br><strong>操作系统就像一个工厂</strong><br></br><br></br><strong>线程值的是一条流水线 整个执行过程的总称 也是一个抽象概念</strong><br></br><strong>线程是CPU的最小执行单位 是具体负责执行代码的</strong><br></br><br></br>进程是一个资源单位,其中包括了改程序运行所需的所有资源<br></br>线程相当于车间里的一条流水线<br></br>线程的特点:<br></br>    一个进程中至少包括一个线程 是由操作系统自动创建的 称之为主线程<br></br>    一个进程中可以有任意数量的线程<br></br>    创建线程的开销对比进程而言 要小的多<br></br>    <strong>同一个进程中的线程间数据是共享的(最主要的特点)</strong><br></br><br></br>如何使用:使用的方式与进程一致<br></br>不同的是:创建线程的代码可以写在任何位置<br></br><br></br>from threading import Thread

多进程(补充),多线程,锁教程多进程(补充),多线程,锁教程

# 第一种 开启线程的方式 直接实例化Thread类
# from threading import Thread
#
# def task():
#     print('running....')
#
#
# if __name__ == '__main__':
#     t=Thread(target=task)
#     t.start()
#     print('over')
#
# # 2.继承Thread类  覆盖run方法
# class MyThread(Thread):
#     def run(self):
#         print('running...')
# MyThread().start()
# #t=MyThread()
# #t.start()

两种线程创建方式


<br></br><br></br><br></br><strong>开启线程速度 比开启进程快很多</strong><br></br><br></br><strong>主线程任务执行完毕后 进程不会立即结束 会等待所有子线程执行完毕</strong><br></br><strong>在同一进程中 所有线程都是平等的 没有子父一说</strong><br></br>from threading import  Thread<br></br>import time<br></br><br></br>def task():<br></br>    print("子线程 running.....")<br></br>    time.sleep(3)<br></br>    print("子线程 over......")<br></br><br></br>t = Thread(target=task)<br></br>t.start()<br></br>print("main over")<br></br><br></br><strong>线程与进程的区别之一 数据是共享的</strong><br></br><strong>区别二 创建进程与创建线程的开销 大约是一百多倍</strong><br></br><br></br>
from multiprocessing import  Process
import os
def task():
    print(os.getpid())
    pass

if __name__ == '__main__':

    start = time.time()
    ps = []
    for i in range(100):
        p = Thread(target=task)
        # p = Process(target=task)
        p.start()
        ps.append(p)

    for p in ps:
        p.join()

    print(time.time()-start)
<br></br><br></br><strong>线程安全也是通过锁来保证  所得用法与进程中一模一样<br></br></strong>

多进程(补充),多线程,锁教程多进程(补充),多线程,锁教程

# import time
# from threading import  Thread,Lock
#
# num = 10
# lock = Lock()
#
# def task():
#     global num
#     # lock.acquire()
#     a = num
#     time.sleep(0.1)
#     num = a - 1
#     # lock.release()
#
#
# ts = []
# for i in range(10):
#     t = Thread(target=task)
#     t.start()
#     ts.append(t)
#
# for t in ts:
#     t.join()
#
#
# print(num)

线程安全





开发高并发程序很有可能遇到安全问题

解决方案只有加锁 但是在使用锁时 很有可能出现死锁问题



出现死锁问题的两种情况:

1.对同一把锁调用了多次acquire 导致死锁问题(最low的死锁问题 应该避免这种问题)

2.有多把锁,一个线程抢一把锁,要完成任务必须同时抢到所有的锁 将导致死锁问题


![多进程(补充),多线程,锁教程](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)![多进程(补充),多线程,锁教程](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)  
  
  

from threading import Lock,Thread
import time

lock = Lock()

lock.acquire()

lock.acquire()

print("over")

一个盘子 和一双筷子

lock1 = Lock()

lock2 = Lock()

def task1(name):

lock1.acquire()

print("%s 抢到了盘子" % name)

time.sleep(1)

lock2.acquire()

print("%s 抢到了筷子" % name)

print("%s 吃饭了....." % name)

lock1.release()

lock2.release()

def task2(name):

lock2.acquire()

print("%s 抢到了筷子" % name)

lock1.acquire()

print("%s 抢到了盘子" % name)

print("%s 吃饭了....." % name)

lock1.release()

lock2.release()

t1 = Thread(target=task1,args=("渣渣辉",))

t1.start()

t2 = Thread(target=task2,args=("大导演",))

t2.start()


死锁   
  
  
  
  
  
  
  



如何避免:

1.能不加锁就不加

2.如果一定要加 要保证锁只有一把



RLock只能防止同一个问题 统一线程多次执行acquire



from threading import RLock

lock = RLock()

lock.acquire()

lock.acquire()

lock.acquire()

lock.acquire()

print("over")

lock = RLock()

def task1():

lock.acquire()

def task2():

lock.acquire()

Thread(target=task1).start()

Thread(target=task2).start()







信号量 Semaphore(num) 可以控制同一时间有多少线程可以并发的访问

不是用来处理线程安全问题



from threading import Semaphore

s_lock = Semaphore(3)

def task():

s_lock.acquire()
time.sleep(1)
print("run.....")
s_lock.release()

for i in range(20):

t = Thread(target=task)
t.start()





threading.current_thread() # 获取当前线程

threading.active_count() 正在运行中的线程数量

threading.enumerate() 返回所有正在运行的线程对象





守护线程会在主线程结束后立即结束 即使任务没有完成

主线程会等待所有子线程全部完成后才会结束





守护线程会在所有非守护线程结束后 结束*



主线 守护线程

主线程要等待所有子线程结束



from threading import Semaphore

s_lock = Semaphore(3)

def task():

s_lock.acquire()
time.sleep(1)
print("run.....")
s_lock.release()

for i in range(20):

t = Thread(target=task)
t.start()

标签: 进程, 线程, 多线程, lock, Thread, 补充, acquire

相关文章推荐

添加新评论,含*的栏目为必填