python-多线程编程

串行程序必须使用非阻塞I/O,或拥有计时器的阻塞I/O,需兼顾要执行的多个任务,难以维护。

多线程编程,以及多线程队列数据结构,包含如下几个执行特定函数的线程:

UserRequestThread:读取客户端输入,放入队列

RequestProcessor:从队列中获取请求并处理

ReplyThread:结果回传用户 or 把数据写入本地数据库

1 线程和进程

1.1 进程:一个运行中的程序

1.2 线程:在同一进程下执行,共享上下文,共享同一片数据空间。当线程运行时,可以被中断和临时挂起

2 线程和python

2.1 全局解释器锁(GIL)

python解释器可以运行多个线程,但任意时刻,只有一个线程会被解释器执行。
(1-设置GIL,2-切换1个线程执行,3-(执行数量的字节码指令 Or 线程让出控制权 time.sleep(0),4-设置线程为睡眠状态,5-解锁GIL))

2.2 退出线程

当一个线程完成函数执行,会退出。也可以通过调用thread.exit()退出函数、sys.exit()退出Python进程、抛出SystemExit异常来使线程退出。

2.3 在python中使用线程

避免使用thread模块,因为对于进程何时退出没有控制。当主线程结束时,所有其他线程也都强制结束。

2.4 thread模块

thread模块提供了基本的同步数据结构---锁对象,核心函数 start_new_thread(func,args),派生新的线程来调用这个函数。此外还有 allocate_lock()---分配锁对象   exit()---退出线程
"start_new_thread() 必须包含开始的2个参数,即使函数func不需参数,也要传递空元祖进去"

"引入锁,目的为了在所有线程结束后立刻退出"

锁对象方法:
1 acquire() 获取
2 locked() 如果获取了 返回True
3 release() 释放


2.5 threading模块

threading模块包含的对象
threading模块支持守护线程,一般是一个等待客户端请求服务的服务器,如果主线程准备退出,不需要等待某个子线程完成,可以给这个子线程设置守护线程标记,需要在启动线程之前赋值语句,thread.daemon = True,一个新的子线程会继承父线程的守护标记。

2.5.1 Thread类

Thread对象属性

name---线程名
ident 线程标识符
daemon--是否是守护线程

Thread对象方法

__init__(group=None, target=None, args())
start()
run()---定义线程功能的方法
join(timeout=None)---直至启动的线程终止之前一直挂起,除非有timeout,否则一直阻塞。

使用Thread类,创建线程的方法:

1 创建Thread实例,传给它一个函数。
   实例化Thread和调用thread.start_new_thread()最大的区别是,新线程不会立即开始执行。通过调用每个线程的start()方法开始执行,join()方法等待线程结束。

2 派生Thread的子类,并创建子类的实例。

class MyThread(threading.Thread):
      def __init__(self, func, args, name=' '):   
            threading.Thread.__init__(self)    #调用父类构造函数初始化父类

为了让子类更加通用,专门配置一个模块,便于以后导入。把结果保存在实例属性中,并新建一个方法来获取值。


python-多线程编程_第1张图片

2.6 单线程和多线程执行对比

你可能感兴趣的:(python-多线程编程)