python之多线程原理

并发

并发:逻辑上具备同时处理多个任务的能力。
并行:物理上在同一时刻执行多个并发任务。

举例:开个QQ,开了一个进程,开了微信,开了一个进程。在QQ这个进程里面,传输文字开一个线程、传输语音开了一个线程、弹出对话框又开了一个线程。
总结:开一个软件,相当于开了一个进程。在这个软件运行的过程里,多个工作同时运转,完成了QQ的运行,那么这个多个工作分别有多个线程。


线程与进程之间的关系

线程和进程之间的区别:


image.png

1.多线程-几个基本概念的了解

进程在python中的使用,对模块threading进行操作,调用的这个三方库。可以通过help(threading)了解其中的方法、变量使用情况。也可以使用dir(threading)查看目录结构。

  • 多线程使用的几个概念:
    r_synchronization=threading.Lock()#同步锁
    r_synchronization.acquire()#调用变量r_synchronization进行上锁,用于业务开始之前先对操作进行上锁操作
    r_synchronization.release()#调用变量r_synchronization解锁,用于业务结束之前对操作进行解锁操作
#递归锁,与同步锁的操作方法保持一致。
r_recursion.acquire() #上锁
r_recursion.release() #解锁
r_recursion=threading.RLock #递归锁
current_thread_n = threading.current_thread()  # 返回当前线程

current_thread_num = threading.active_count()# 返回正在运行的线程数量
run_thread_len = len(threading.enumerate())# 返回正在运行的线程数量
run_thread_list = threading.enumerate() # 返回当前运行线程的列表
t1=threading.Thread(target=dance)#创建两个子线程,参数传递为函数名
t1.setDaemon(True)# 设置守护进程,守护进程:主线程结束时自动退出子线程。
t1.start()# 启动子线程
t1.join()# 等待进程结束exit()`# 主线程退出,t1子线程设置了守护进程,会自动退出。其他子线程会继续执行。

2.实例-几个概念的使用

import threading,time
def dance():
    for i in range(5):
        print('我在唱歌')
        time.sleep(1)

def wu():
    for i in range(5):
        print('我在跳舞')
        time.sleep(0.5)

if __name__=='__main__':
    #创建两个子线程,参数传递为函数名
    t1 = threading.Thread(target=dance)
    t2 = threading.Thread(target=wu)
    #设置守护进程,守护进程:主线程结束时自动退出子线程。
    t1.setDaemon(True)
    #启动子线程
    t1.start()
    t2.start()
    #等待进程结束
    t1.join()
    t2.join()
    print('over')
    #主线程退出,t1子线程设置了守护进程,会自动退出。t2子线程会继续执行。
    exit()
    current_thread_n= threading.current_thread()  # 返回当前线程
    # 返回正在运行的线程数量
    current_thread_num=threading.active_count()
    run_thread_len=len(threading.enumerate())
    run_thread_list=threading.enumerate()  # 返回当前运行线程的列表

3.不安全的并发-同步锁

  • 场景:2件事情都需要操作一个变量,几乎同时发生,这个时候,显然并发操作是不安全的。
  • 解决方案:上锁(有2种方法:threading.Lock()-同步锁、threading.RLock()-递归锁)
import threading,time
account_account =500 #银行账号500元
r =threading.Lock() #一把锁,同步锁

#操作一个银行账号
def foo(num):
    r.acquire() #上锁
    global account_account #申明全局变量的引用
    balance =account_account #通过接口调用到账号
    time.sleep(1)
    balance = balance+num
    account_account =balance #计算结束,要将结果存回数据库或者通过接口返回新的余额。
    r.release() #解锁
t1 =threading.Thread(target=foo,args=(10000,)) #收入
t2 =threading.Thread(target=foo,args=(-200,))#把钱发出去
#启动线程
t1.start()
t2.start()
t1.join()
t2.join()
print('最终余额:',account_account)

4.不安全的并发-递归锁

#递归锁
import time,threading
# lockA =threading.Lock() #面试人员的锁
# lockB = threading.Lock() #小红的锁
r =threading.RLock() #递归锁
def foo1():
    r.acquire()#上锁
    print('请解释什么是死锁')
    time.sleep(1)

    r.acquire() #上锁
    print('发offer')

    #解锁
    r.release()
    r.release()

def foo2():
    r.acquire()
    print('请给我offer')
    time.sleep(1)

    r.acquire()
    print('向面试官解释什么是死锁')
    time.sleep(1)

    r.release()
    r.release()

t1 =threading.Thread(target=foo1) #收入
t2 =threading.Thread(target=foo2)#把钱发出去

t1.start()
t2.start()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本篇主要讲的是多线程和多进程的一些基础知识,包括并发、并行、进程、线程相关概念以及线程的创建与调用、阻塞线程和守护...
    筱媛媛阅读 745评论 4 16
  • 多进程之间不共享数据,程序上下文区分开。 多线程之间共享数据,在数据处理上要谨慎 1.定义 程序: 只是一组指令的...
    SkTj阅读 4,184评论 0 2
  • 以前我们接触的都是单线程单进程的python编程方式,从今天开始我们开始接触多线程和多进程的开发模式。首先多线程就...
    He阅读 237评论 0 1
  • 1.进程与线程的概念 一个进程管理多个线程,进程是爹妈,管着众多的线程儿子.开一个QQ,开了一个进程.开了迅雷,开...
    Explorer_Mi阅读 198评论 1 0
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 10,616评论 0 11