、、线程是最小的执行单元,而进程由至少一个线程组成,多任务可以由多进程完成,也可以由一个进程内的多线程完成。启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行。x由于任何进程默认就会启动一个线程,我们把该线程称为主线程,主线程又可以启动新的线程,Python的threading模块有个current_thread()函数,它永远返回当前线程的实例。主线程实例的名字叫MainThread,子线程的名字在创建时指定,我们用LoopThread命名子线程。名字仅仅在打印时用来显示,完全没有其他意义,如果不起名字Python就自动给线程命名为Thread-1,Thread-2……
、、线程的注意点:为了使主程序结束以后,所有的子程序也停止运行,我们需要对主程序进行守护:线程名.thread.setDaemon(True)
具体案例如下:
def demo():
for i in range(5):
print('正在写代码')
time.sleep(1)
if __name__ == '__main__':
# 创建子线程
first_thread = threading.Thread(target=demo)
# 守护主线程,当主线程退出的同时,销毁所有的子线程
first_thread.setDaemon(True)
子线程开始运行
first_thread.start()
time.sleep(2)
print('主线程退出')
exit()
自定义线程的创建方法:
为了可以调用start方法,我们使用父类的父类的初始化方法,使用库中对线程定义的线程初始化方法,即可调用start方法,从来调用run方法
import threading
# 创建一个线程类
class My_thread(threading.Thread):
def __init__(self,name):
# 使用父类的父类的初始化方法,可以使用start调用,start内部调用run方法
super(My_thread,self).__init__()
self.name=name
def show_name(self):
print('这是我自己的名字',self.name)
# 重新编写run方法
def run(self):
self.show_name()
if __name__ == '__main__':
mythread=My_thread('林俊杰')
mythread.run()
互斥锁
多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。
为了防止资源抢夺,我们可以对进程加锁。其命令为
#创建互斥锁
lock=threading.Lock()
# 上锁
lock.acquire()
# 释放锁
lock.release()
互斥锁案例
import threading
# 全局变量
num = 0
# 任务一:
def work1(number):
# 上锁
lock.acquire()
global num
for i in range(number):
num += 1
print('此时Num等于',num)
lock.release()
# 任务二:
def work2(number):
# 上锁
lock.acquire()
global num
for i in range(number):
num += 1
print('此时Num等于', num)
lock.release()
# 创建互斥锁
lock=threading.Lock()
if __name__ == '__main__':
t1 = threading.Thread(target=work1,args=(10000000,))
t2 = threading.Thread(target=work2, args=(10000000,))
t1.start()
t2.start()
使用互斥锁的时候,
可能会出现死锁的情况,比如两个变量,两个线程需要两个变量才能进行下一步,但是分别抢夺了一个变量,程序运行不下去,所以在 程序设计的时候要避免死锁的出现,也可以添加超时时间来跳出死锁。
多进程实现任务,(与多线程类似)
命令:multiprocessing.Process(target=func)
库:import multiprocessing
import multiprocessing
import time
my_list = list()
def work1():
for i in range(5):
my_list.append(i)
time.sleep(0.5)
def work2():
print(my_list)
if __name__ == '__main__':
process_1=multiprocessing.Process(target=work1)
process_2=multiprocessing.Process(target=work2)
process_1.start()
process_1.join()
process_2.start()
多线程全局变量不共享
import multiprocessing
import time
# 全局变量
mylist = list()
def write():
for i in range(5):
mylist.append(i)
time.sleep(0.3)
# 任务2:读数据
def read():
print(mylist)
if __name__ == '__main__':
t1 = multiprocessing.Process(target=write)
t2 = multiprocessing.Process(target=read)
t1.start()
t1.join()
t2.start()
多进程传参问题
import multiprocessing
import os
import time
def show(word,name,age):
print('word:%s,name:%s,age:%d'%(word,name,age))
if __name__ == '__main__':
#加,是为了声明前面的数据不是字符串,有逗号表示这是一个只有一个元素的元组。
没有逗号表示这是这是一个高优先级的表达式。
process = multiprocessing.Process(target=show,args=('hello',),kwargs={'name':'wang','age':18})
process.daemon = True
process.start()
time.sleep(1)
process.terminate()
消息队列:进程之间数据不共享,为了共享数据,将需要共享的参数传入消息队列,然后穿给另一个进程。命令库:multiprocessing
import multiprocessing
if __name__ == '__main__':
queue = multiprocessing.Queue(maxsize=3)
# 向队列里面放入消息。最大数据数量为3
queue.put('hello')
queue.put(1)
queue.put([1,2,3])
# queue.put({'a':1},timeout=0.1)
# 被注释掉的语句为 放入第四个数据,0.1s 放不进去就跳过
print(queue)
print(queue.get())
print(queue.get())
print(queue.get())
输入三个值
print(queue.get(timeout=1))
等待输出第四个值,timeout1s以后,抛出错误没有第四个值,
进程池
import multiprocessing
import os
import time
def copy(index):
print('当前进程的编号',os.getpid())
print(index)
time.sleep(1)
if __name__ == '__main__':
pool = multiprocessing.Pool(4)
#最大容纳进程数 4
for i in range(10):
pool.apply_async(copy,(i,))
#十个经常等待运行,同时运行三个,完成一个,第四个补进来
pool.close()
pool.join()
# join的作用:主进程阻塞,等待子进程