什么是线程和进程
进程指的是一个程序执行的过程,是一个资源单位。它包含了操作系统开辟内存空间,将应用程序加载到内存中以及执行应用程序代码的整个过程。就像是一个车间内的一个小工厂一样,整个的生产过程被称之为一个进程。
线程是操作系统真正的执行单元。它仅仅代表的是进程中的最后一步,也就是执行应用程序代码的过程。就像是车间里的一条条流水线一样,是真正的用来执行代码的一个过程。
线程和进程的区别
进程占用开销较大,这是因为进程要重新开辟一段内存空间,线程开销较小。
进程之间内存是物理隔离的,但是同一进程内的线程之间内存是共享的。注意不同进程之间的线程通信还是需要通过队列进行通信的。
from threading import Thread
import time
开启线程的两种方式
通过类Thread
因为线程开销较小的原因,我们会发现结果是先打印task里面的内容,然后打印主线程三个字,这个和进程正好相反。
from threading import Thread
import time
def task():
print('thread is running ....')
time.sleep(3)
Thread(target=task).start()
print('主线程')
通过继承类Thread
我们创建一个线程并且执行的过程本质上就是创建内存之后执行Thread类的run函数,因此我们可以通过继承类的方式去创建。
from threading import Thread
import time
class MyThread(Thread):
def run(self):
print('thread is running ....')
time.sleep(3)
MyThread().start()
print('主线程')
线程相关的属性方法
# current_thread() 当前线程对象,.name是里面的一个属性,可以得到线程名称,主线程名称为MainTread
# active_count() 当前活跃的线程数,记得还有一个主线程
# enumerate 返回一个列表,里面都是当前活跃的线程数目
from threading import Thread, current_thread, active_count, enumerate
import time
def task():
print('%s is running' % current_thread().name)
time.sleep(3)
#: name表示自定义线程名称
t = Thread(target=task,)
t.start()
print(current_thread().name)
print(active_count())
print(enumerate())
守护进程与守护线程
守护进程
对于进程而言,如果代码中有守护进程,也有非守护进程,等主进程代码执行完毕之后守护进程也就结束了,并不会等待非守护进程的执行。
from multiprocessing import Process
守护线程
对于线程而言,如果代码中有守护线程,也有非守护线程,等主线程代码执行完毕之后并不会终止守护线程的执行,只有等到所有的非守护线程执行完毕之后才意味着主线程的结束,此时才会总之守护线程。
将上面的代码的进程改成线程,就会出现不一样的效果。
from threading import Thread
import time
互斥锁
线程中的互斥锁和进程中的互斥锁都是为了解决多个进程或者线程同时访问同一个系统资源时出现数据混乱的问题,不同之处在于所使用模块不一样,因此线程互斥锁只能在线程中使用,进程互斥锁只能在进程中使用。
不使用线程锁的问题
from threading import Thread
import time
x = 100
def task():
global x
temp = x
time.sleep(0.1)
x = temp - 1
#: 创建100个线程全局变量x进行修改,每次减1
t_l = []
for i in range(100):
t = Thread(target=task)
t_l.append(t)
t.start()
# 用来等待所有线程结束
for i in t_l:
i.join()