02-02-01

不管进程还是线程,主都会等着子结束而结束这是因为子进程/线程在执行的时候,会暂用一些资源,主就要收回这些资源

线程是系统调度的基本单位,进程是系统资源的基本单位

主线程会等待子线程结束才结束

import threading
import time

def sayHello():
print("------")
time.sleep(1)


for i in range(5):
t = threading.Thread(target=sayHello)
t.start()

print("*******")
Result:

------
------
------
------
------

******* #多个线程执行同一个函数,不会互相影响

#####################使用thread子类完成创建多线程###########
import threading
import time

class myThread(threading.Thread):
def run(self):
for i in range(3):
time.sleep(1)
print(self.name+"num"+str(i)) #self.name保存的是当前的线程名字


if __name__ == "__main__":
t = myThread()
t.start() #MyThread没有start方法,为啥可以使用呢,这是threading.Thread中start去调用myThread的run方法

线程的执行顺序:

线程的执行顺序没有固定的,各个线程执行顺序不固定

线程共享全局变量:

线程全局变量是共用的,一个线程的更改其它线程使用也是更改的;而进程是相互独立的,一个进程修改不会对另一个进程产生影响

import time
import threading
g_num = 0

def work1():
global g_num
g_num += 1
print("work1, gum is %d"%g_num)

def work2():
global g_num
print("work2, gum is %d"%g_num)

t1 = threading.Thread(target = work1)
t1.start()
time.sleep(1)
t2 = threading.Thread(target = work2)
t2.start()
result:

work1, gum is 1
work2, gum is 1

列表作为参数传递也可以共享,变量不行需要global
import time
import threading

def work1(g_num):
g_num.append(4)
print("work1, guum is", g_num)

def work2(g_num):
time.sleep(1)
print("work2, guum is", g_num)

g_num = [1,2,3]
t1 = threading.Thread(target = work1, args=(g_num,))
t1.start()
t2 = threading.Thread(target = work2, args=(g_num,))
t2.start()

Result:

work1, guum is [1, 2, 3, 4]
work2, guum is [1, 2, 3, 4]

 ####互斥锁

当多个线程同时竞争同一个资源的的时候

互斥锁是加的code范围越小越好,加的太多越来越像单任务

比如下面如果在for循环外面加就跟单任务很相似

import threading

g_num = 0

def work1():
global g_num
#这个线程和work2都在抢着对这个锁进行上锁,如果一方的锁上锁成功,那么另一方需要需要一直等待,知道这个锁释放为
for i in range(1000000):
mutex.acquire()
g_num += 1
mutex.release() #解锁
print("work1, guum is %d"%g_num)

def work2():
global g_num
for i in range(1000000):
mutex.acquire()
g_num += 1
mutex.release()
print("work1, guum is %d"%g_num)

#创建一把锁,这个锁默认是没有上锁的
mutex = threading.Lock()
t1 = threading.Thread(target = work1)
t1.start()
#t1.join()
t2 = threading.Thread(target = work2)
t2.start()
#t2.join()

多线程使用非共享变量

创建一个函数,多线程访问一个函数时,每个线程访问这个函数的变量值时独有的
通过线程名来判断
import threading
import time


def work1():

name = threading.current_thread().name #取线程名字比如 Thread-1 Main thread...
print("---thread name---%s"%name)
num = 0
if name == "Thread-1":
num += 1
else:
time.sleep(1)
print("thread name is %s---num is %d"%(name, num))


t1 = threading.Thread(target = work1)
t1.start()
#t1.join()
t2 = threading.Thread(target = work1)
t2.start()
#t2.join()
result:

---thread name---Thread-1
thread name is Thread-1---num is 1
---thread name---Thread-2
thread name is Thread-2---num is 0

死锁以及解决方法

加入超时时间:

注意acquire()这个上锁方法是阻塞的等在条件满足,不满足条件一直会卡在这里,下面就是一个死锁

class MyThread1(Thread):
def run(self):
if mutex1.acquire():
print("----------")
time.sleep(1)
if mutex2.acquire():
print("**********")
mutex2.release()


class MyThread2(Thread):
def run(self):
if mutex2.acquire():
print("###############")
time.sleep(1)
if mutex1.acquire():
print("$$$$$$$$$$")
mutex1.release()


if __name__ == "__main__":
mutex1 = Lock()
mutex2 = Lock()
t1 = MyThread1()
t2 = MyThread2()
t1.start()
t2.start()
result:

----------
###############

 

 



 mutex.acquire(2)###2s之后还不能上锁的化,就继续往下走

同步的理解与应用
代码按照一定规律去执行, 不然很难保证task1 task2 task3依次输出
按照规定的先后顺序执行
import threading
import time

class Task1(threading.Thread):
def run(self):
while True:
if lock1.acquire():
print("----Task1----")
time.sleep(1)
lock2.release()

class Task2(threading.Thread):
def run(self):
while True:
if lock2.acquire():
print("----Task2----")
time.sleep(1)
lock3.release()

class Task3(threading.Thread):
def run(self):
while True:
if lock3.acquire():
print("----Task3----")
time.sleep(1)
lock1.release()


if __name__ == "__main__":
lock1 = threading.Lock()
lock2 = threading.Lock()
lock2.acquire()
lock3 = threading.Lock()
lock3.acquire()
t1 = Task1()
t2 = Task2()
t3 = Task3()
t1.start()
t2.start()
t3.start()
result:

----Task1----
----Task2----
----Task3----
----Task1----
----Task2----
----Task3----
----Task1----
----Task2----

....

 

 

 异步: 就是不确定哪一个先执行

posted @ 2021-07-13 09:51  狼太白  阅读(48)  评论(0编辑  收藏  举报