1.作业
1.1必会题
1.什么是多任务编程?多任务编程有哪些实现方式?列举一些生活中进行多任务的案例。
多任务是指在同一时间内,同时去做多个事情
在多任务编程时,可以使用进程,线程和协程的方式来实现多任务编程。
生活中的案例:一边唱歌,一边跳舞
2.线程在执行时有什么特点?
线程是程序执行的最小执行单位,由CPU进行调度执行
线程在执行时是无序的,不能对线程的执行顺序进行控制
3.如何解决在线程共享数据时出现的资源竞争问题?
在多个线程同时对同一个全局变量进行操作时,会有可能出现 资源竞争数据错误的问题
可以通过在程序中加入互斥锁来解决共享变量的资源竞争问题。
互斥锁为资源引入的一个状态,锁定、非锁定
抢到锁的线程先执行,没有抢到锁的线程需要等待,等锁用完后需要释放,然后其他等待的线程再去抢这个锁,那个线程抢到那个线程再执行。
具体那个线程抢到这个锁,我们决定不了,是由CPU调度决定的
4.造成死锁的原因是什么?如和避免死锁?
死锁是指由于两个或者多个线程相互持有对方所需要的资源,导致这些线程处于等待的状态,无法前往执行,而导致程序进入一种阻塞状态。
可以通过在合理的时间释放锁或资源来避免造成死锁的产生
1.2 每日练习题
1.什么是多任务
同一时间做多个任务
2.什么是并发
指的是任务数多于CPU核数,通过操作系统的各种任务调度算法,实现用多个任务“一起”执行(实际上总有一些任务不在执行,因为切换任务的速度相当的快,看上去一起执行了而已)
3.什么是并行
指的是任务数小于等于CPU核数,即任务真的是一起执行的
4.如何创建并启动一个线程
t = threading.Thread(target=func_name) # 注意:这里的方法名不要加括号t.start()
5.如何获取当前程序活动线程列表
注意:
只有启动的线程才能加入到活动线程列表threading.enumerate()
6.如何获取当前指定代码所在的 线程
threading.current_thread()
7.如何在创建子线程的时候为任务传参t.threading.Tread(target=func_name,arg=(params,)) # 注意:这里的args是元组,当只有一个参数的时候记得在后面加一个,
或者
t.threading.Thread(target=func_name,kwarg={'key':'value'})
8.线程的执行顺序是什么样的?
线程的执行总是无序的
9.设置守护线程的作用是什么?如何设置线程为守护线程?
设置守护线程是为了主线程结束时不等待子线程,子线程直接结束创建子线程时加入参数:threading.Thread(target=func_name,daemon=True)
或者调用setDaemon方法: t.setDaemon(True)
10.自定义线程类如何启动?时调用类中的run吗?
自定义线程类中虽然有run方法,但是同意执行入口还是start()方法,start()方法会默认调用run方法
11.join方法有什么作用
t.join()会阻塞直到当前子线程任务结束
join()可以传参数timeout,阻塞timeout秒之后打通阻塞继续向下执行
12.线程间能不能共享全局变量
可以
13.线程间共享全局变量会出现什么问题
会导致数据不安全
14.如和解决多线程共享全局变量出现的问题
使用join()函数执行完一个任务之后再执行第二个任务使用互斥锁
1.创建锁对象: lock = threading.Lock()
2.获取锁资源: lock.acquire()
3.执行功能代码
4.释放锁资源: lock.release()
15.什么是同步?
同步就是协同步调,按预定的先后次序进行运行。如你说完,我再说。‘同’字从字面上容易理解为一起动作,其实不是,“同”字应该是指协同、协助、互相配合。
1.3 企业笔试题
1.什么是多线程竞争
线程是非独立的,同一个进程里线程是数据共享的,当各个线程访问数据资源时会出现竞争状态,即:数据几乎同步会被多个线程占用,造成数据混乱,即所谓的线程不安全,那么怎么解决度线程竞争问题?----锁
锁的好处:
确保了某段关键代码(共享数据资源)只能由一个线程从头到尾完整完整的执行
能解决多线程资源竞争下的数据错乱问题
锁的坏处:阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大的降低了,锁的致命问题:死锁
2.解释一下什么是锁,有哪些锁?
锁是python中提供的对线程控制的对象。有互斥锁、可重入锁、死锁
3.什么是死锁?
若干子线程在系统资源竞争时,都在等待对方对某部分资源解除占用状态,结果是谁也不愿意先解锁,互相干等着,程序无法执行下去,这就是死锁。GIL锁(有的时候,面试官不问,你自己要主动说,增加b格,尽量别一问一答的尬聊,不然等到最后就是一句,你还有什么想问的么?)GIL锁 全局解释器锁(只在python中有)作用:限制多线程同时执行,保证同一时间只有一个线程执行,所以cpython里的多线程其实是伪 多线程。
所以python里常常使用协程技术来代替多线程,协程是一种更轻量级的线程,进程和线程的切换是由系统决定,而协程由我们程序员直接决定,而模块gevent下切换是遇到了耗时操作才会切换,三者的联系,进程里有线程,线程里有协程
4.什么是线程安全,什么是互斥锁
每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问对象,同一个进程中多线程之间是共享系统资源的,多个线程同时对一个对象进行操作,一个线程操作尚未结束,另一个线程已经对其进行操作,导致最终结果出现错误,此时需要对被操作对象添加互斥锁,保证每个线程对该对象的操作都得到正确的结果
5.说说下面的几个概念,同步、异步、阻塞、非阻塞
同步:多个任务之间有先后顺序执行,一个执行完下个才能执行。
异步:多个任务之间没有先后顺序,可以同时执行有时候一个任务可能要在必要时候获取另一个同时执行的任务的结果,这个就叫 回调
阻塞:如果卡住了调用者,调用者不能再继续往下执行,就是说调用者阻塞了。
非阻塞:如果不会卡主,可以继续执行,就是说非阻塞的
同步异步相对于多任务而言,阻塞非阻塞相对于代码执行而言