多线程

多线程

什么是线程

进程是操作系统调度以及进行资源分配的基础单位,是一个资源单位

线程是操作系统可以运算调度的最小单位,是真正的执行单位,其包含在进程中,一个线程就是一条固定的控制流程。

  • 一个进程可以包含多个线程,同一进程中的线程共享进程内的资源

  • 特点:系统会为每一个进程自动创建一条线程,称之为主线程,后续通过代码开启的线程称之为子线程(并不是父子关系,只是这么称呼)

进程对比线程

  1. 进程是一个资源单位,线程是执行单位

  2. 创建进程的开销远大于线程

  3. 多个进程之间内存是相互隔离的,而线程是共享进程内的所有资源

  4. 进程之间是竞争关系,线程是协作关系

  5. 进程之间有层级关系,而线程之间没有

开启线程也是需要消耗资源的

如果把计算机比喻成一个工厂,那么进程可以看做一个车间,而线程则是流水线

为什么要用线程

  1. 有多个任务要并发处理
  2. 当要并发的任务量大的时候,不能使用进程(资源开销大)

CPython的全局锁

使用线程的方法

和使用进程类似,因为本身就是先创造进程,后来发现进程的资源消耗太高,才有的线程,而线程也是继承与进程的

  • 方法一:实例化对象
from threading  import Thread

def task():
    print("bar run")

# 与进程不同之处1   不需要加判断 开启线程的代码放哪里都可以,因为他不会导入这个文件
t = Thread(target=task)
t.start()
print("over")
  • 方法二:继承

  • 和线程一样,在需要高度自定义的时候使用

from threading import Thread

class MyThread(Thread):

    def run(self):
        # 把要在子线中执行的代码放入run中
        print("bar run")

mt = MyThread()
mt.start()
print("over")

线程安全问题

  • 只要你并发的访问了同一个资源,就一定会产生安全问题,线程的解决方案和进程一直,就是给操作公共资源的代码加锁
  • 线程间可以访问数据
from threading import Thread,Lock
import time
a = 10

l = Lock()

def task():
    global a
    l.acquire()
    temp = a
    time.sleep(0.1)
    a = temp - 1
    l.release()

ts = []
for i in range(10):
    t = Thread(target=task)
    t.start()
    ts.append(t)
for t in ts:t.join()

print(a)
0

守护线程

概念同进程

默认情况下,主线程即使代码执行完毕,也会等待所有非守护线程完毕后程序才能结束 因为多个线程之间是协作关系 。

from threading import Thread
import time

def task1():
    print('t1开始了')
    time.sleep(5)
    print('t1结束了')
    
def task2():
	print('t2开始了')
	time.sleep(3)
	print('t2结束了')
    
print('主开始了哦')

t1 = Thread(target=task1)
t2 = Thread(target=task2)

t1.daemon = True

t1.start()
t2.start()

print('主结束了哦')

主开始了哦
t1开始了
t2开始了
主结束了哦
t2结束了

线程中的常用属性和方法

from threading import  Thread,currentThread,enumerate,activeCount
import time

# t = Thread()
# t.start()
# t.join()
# t.is_alive()	# 是否存活
# t.isAlive()	# 和上面一样,只是写法是小驼峰为了照顾其他程序员
# t.ident  # 线程标识符   id
# t.daemon

# 获取当前线程对象
# print(currentThread())	# <_MainThread(MainThread, started 6732)>
# t = Thread(target=lambda :print(currentThread()))	# <Thread(Thread-1, started 848)>

# 线程可以用lambda,进程不可以
t = Thread(target=lambda :time.sleep(1))
t.start()

t = Thread(target=lambda :time.sleep(1))
t.start()
# 获取正在运行的所有线程对象  是一个列表
print(enumerate())	# 三个进程的列表,主进程和两个子进程

# 存活的线程数量
print(activeCount())	# 3
posted @ 2019-07-04 20:52  abcde_12345  阅读(155)  评论(0编辑  收藏  举报