标签:访问 __init__ 之间 oba star code func play 决定
1 from threading import Thread 2 import threading 3 import os 4 import time 5 6 def func(num): 7 for i in range(5): 8 time.sleep(0.1) 9 print("当前线程号为<--%d--> 它是子线程中的第<--%d-->个"%(num, i)) 10 11 # 创建出5个进程 12 for i in range(4): 13 T = Thread(target=func, args=(i,)) 14 T.start() 15 16 # 查看当前的线程数量 , 包含主进程 17 num_threading = len(threading.enumerate()) 18 print(num_threading)
线程的调用是随机的,它和进程一样,取决于系统的调度算法, 线程运行的实质是每一个线程在cpu的一个核心上轮流占用
1 import threading 2 import time 3 4 class play(threading.Thread): 5 def __init__(self, num): 6 # 这里继承父类的__init__方法是因为防止父类的__init__方法被重写 7 threading.Thread.__init__(self) 8 self.num = num 9 10 def run(self): # 这里必须定义一个run方法, 因为调用线程时run方法决定了类的执行方式 11 time.sleep(0.1) 12 for i in range(5): 13 print("当前线程号为<--%d--> 它是子线程中的第<--%d-->个"%(self.num, i)) 14 15 for i in range(5): 16 t = play(i) # 这里可以直接实例化一个线程的类,直接开启线程 17 t.start()
通过这种方法来创建线程时,一定要在继承threading.Thread的子类中定义一个run方法,当调用这个类时,会直接自动调用run方法
因为线程实际上是共用一个cpu的核心的,所以线程之间的数据是可用共享的, 一个进程内的所有线程共享全局变量
线程不安全现象:
若不能有效的控制多个进程对同一资源的访问,会对资源数据产生破坏,使得线程的结果不可预期
为了解决线程不安全,引入了互斥锁,当某个线程要修改共享数据时,先将其锁定,资源的访问状态为: 锁定 ,此时其他线程不能更改;一直到该线程释放了资源,这时资源的访问状态更改为:非锁定,其他线程才能继续锁定该资源,保证了每次只有一个线程在操作共享资源。
1 from threading import Thread, Lock 2 3 num = 0 4 5 def func1(): 6 global num 7 for i in range(100): 8 L.acquire(True) # acquire中的参数True表示堵塞,若资源被其他线程上锁则一直等待 False则表示非阻塞 9 num += 1 10 L.release() # 将资源解锁 11 print(num) 12 13 def func2(): 14 global num 15 for i in range(100): 16 L.acquire(True) 17 num +=1 18 L.release() 19 print(num) 20 21 L = Lock() 22 23 t1 = Thread(target=func1, ) 24 t2 = Thread(target=func2, ) 25 26 t1.start() 27 t2.start()
acquire() 表示上锁,release() 表示解锁
标签:访问 __init__ 之间 oba star code func play 决定
原文地址:https://www.cnblogs.com/hgzero/p/8976827.html