先简单理解下程序,进程,线程的关系
-
程序是指一段静态的代码
-
进程是指正在执行的程序,将静态的代码运行起来
-
线程是指正在执行程序的小单元
理解线程之前,先简单理解一下进程。进程的三大特征:独立性、动态性、并发性。
-
独立性:指进程是系统中独立存在的实体,拥有独立的资源
-
动态性:这是相对于程序而言的,程序是一段静态的代码,而进程是活动的,拥有自己的生命周期。
-
并发性:多个进程可以在单个处理器上并发执行,互不影响。
线程是进程的执行单元,在程序中,线程是独立的、并发的执行流。
-
每个线程有自己的堆栈,自己程序计数器,自己的局部变量,这里体现了线程的独立性。
-
相同父进程下的所有线程共享进程独立的内存单元(资源+代码),为此可以实现线程间的相互通信。
-
多个线程之间也可以并发执行,互不影响。
线程的创建和启动
创建线程是在 start开启后才算创建完成
通过threading.Thread()来创建线程
import time
import threading
def a1():
for i in range(3):
print(f"a1,{i}")
time.sleep(2)
def a2():
for i in range(3):
print(f"a2,{i}")
time.sleep(2)
def main():
t1 = threading.Thread(target=a1)
t1.start()
t1.join()
# 子程序运行完成后再运行下面的程序
t2 = threading.Thread(target=a2)
t2.start()
print("---------------------------")
if __name__ == '__main__':
main()
- threading.enumerate() :查看线程数量
- join() :子线程运行后再运行主程序
- setDaemon(True):防护线程,不等子程序结束就直接运行主程序
继承threading.Thread来创建线程
import time
import threading
# 继承threading.Thread来创建线程
class A(threading.Thread):
def __init__(self, name):
super().__init__(name=name)
def run(self):
for i in range(4):
print(i)
time.sleep(1)
def main():
print(threading.enumerate())
t = A('test_name')
t.start()
print(threading.enumerate())
if __name__ == '__main__':
main()
线程之间共享全局变量
import threading
import time
# 线程之间共享全局变量。
num = 100
def demo1():
global num
num+=1
print(f"demo1------{num}")
def demo2():
global num
num+=2
print(f"demo2------{num}")
def main():
t1 = threading.Thread(target=demo1)
t2 = threading.Thread(target=demo2)
t1.start()
time.sleep(1)
t2.start()
time.sleep(1)
if __name__ == '__main__':
main()
传递多个参数
import time
import threading
num = [2,3]
def demo1(num):
num.append(33)
print(f"demo1 ---------{num}")
def demo2(num):
print(f"demo2 ---------{num}")
def main():
# t1 = threading.Thread(target=demo1, args=(num,))
t1 = threading.Thread(target=demo1, kwargs=({"num":[6,9,0]}))
#这里的键名要与 函数demo1 的形参一致
t2 = threading.Thread(target=demo2, args=(num,))
# 当只有一个参数的时候,需要在参数后面加上逗号,
t1.start()
time.sleep(1)
t2.start()
time.sleep(1)
print(f"main----{num}")
if __name__ == '__main__':
main()