Forking and Threading:
线程:
是操作系统能够进行运算调度的最小单位,是进程中的实际运作单位,
一条线程指进程中一个单一顺序的控制流,一个进程可以并发多个线程。
进程:
程序并不能单独运行,只有在将程序装载到内存中,系统为他分配资源才能运行,
而这种执行的程序被称之为进程。
执行多线程的两种方法;
1.直接调用
import threading
import time
def myThreading(num):
print('running on number:%s'%num)
time.sleep(3)
print('end number:%s'%num)
if __name__ == '__main__':
t1 = threading.Thread(target=myThreading,args=(1,))
t2 = threading.Thread(target=myThreading,args=(2,))
t1.start()
t2.start()
--------------------------
2.类实例式调用:
import threading
import time
class MyThreading(threading.Thread):
def __init__(self,num):
self.num = num
threading.Thread.__init__(self)
def run(self):
print('running on number:%s'%self.num)
time.sleep(self.num)
print('end number:%s'%self.num)
if __name__ == '__main__':
t1 = MyThreading(1)
t2 = MyThreading(2)
t1.start()
t2.start()
3.join() and setDaemon(Ture)
t1.join()
在t1子进程结束后,该父进程才结束
t1.setDaemon(Ture)
将线程声明为收获线程,必须在start()之前设置,在主线程结束后,
该设置的子线程一起结束,不管是否执行完毕。
4.Thread的其他方法:
threading.currentThread() #返回当前的线程变量
threading.enumerate() #返回一个包含正在运行的线程的list。
threading.activeCount() #返回正在运行的线程数 = len(threading.enumerate())
t1.run() #用于表示线程活动的方法
t1.start() #开启线程
t1.join() #阻塞主进程
t1.setDaemon() #守护线程
t1.isAlive() #返回线程是否活动
t1.getName() #获取线程名
t1.setName() #设置线程名
多线程锁:
同步锁:
保证数据的唯一性,在同一时刻只有一个线程操作数据。
#获取一个锁 ----lock = threading.Lock()
#对操作加锁 ----lock.acquire()
#结束释放锁 ----lock.release()
import threading
import time
def addNum():
global num
lock.acquire()
temp=num
print('get num:---',num)
time.sleep(0.1)
num = temp - 1
lock.release()
num = 100
thread_list = []
lock = threading.Lock()
for i in range(100):
t = threading.Thread(target=addNum)
t.start()
thread_list.append(t)
for t in thread_list:
t.join()
print('final num:',num)
GIL:
pass
线程死锁,递归锁:
lockA = threading.Lock()
lockB = threading.Lock()
同时使用多把锁,并且嵌套使用的时候就会出现死锁的现象,解决死锁使用递归锁。
lock = threading.RLock()
lock.acquire()
lock.acquire()
lock.release()
lock.release()
RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次acquire,
直到一个线程的所有的acquire都被release,其他的线程才能获得资源。