线程

2019-03-05  本文已影响0人  Ginta

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务

简单实现

import threading
import time

def run(n):
    print("task", n)
    time.sleep(2)
    print("task has done", n)

start_time = time.time()
for i in range(50):
    t = threading.Thread(target=run, args=("t-%s" %i,))
    t.start()

print("all threads have finished!")
  1. 定义执行函数
  2. 然后实例化Thread类
  3. 其中target就是线程执行的函数, args是函数参数,元组形式

等待线程

程序的最外面执行的是主线程,我们没法控制,上述程序在我们子线程执行的过程中虽然有延迟2s,但是主线程依旧在执行,并且会在执行完毕后程序就结束了,此时子线程还没结束,我们想让程序等待子线程,就要用到join()方法。join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞直到线程结束,如果结束则跳转执行下一个线程的join函数。

import threading
import time

def run(n):
    print("task", n)
    time.sleep(2)
    print("task has done", n)

t_objs = []
start_time = time.time()
for i in range(50):
    t = threading.Thread(target=run, args=("t-%s" %i,))
    t.start()
    t_objs.append(t)

for i in t_objs:
    i.join()

print("all threads have finished!")
print("const: ", time.time()-start_time)

守护线程

有些线程执行后台任务,比如发送keepalive包,或者执行定期垃圾收集,等等。这些只有在主程序运行时才有用,并且在其他非守护进程线程退出时可以将它们删除。如果没有守护线程,在程序完全退出之前,您必须跟踪它们,并告诉它们退出。通过将它们设置为守护线程,您可以让它们运行并忘记它们,当您的程序退出时,任何守护线程都会自动被杀死

import threading
import time

def run(n):
    print("task", n)
    time.sleep(2)
    print("task has done", n)

t_objs = []
start_time = time.time()
for i in range(50):
    t = threading.Thread(target=run, args=("t-%s" %i,))
    t.setDaemon(True) # 设置守护线程,主线程不需要等待它
    t.start()
    t_objs.append(t)

for i in t_objs:
    i.join()

print("all threads have finished!")
print("const: ", time.time()-start_time)

线程锁

一个进程下的线程共享该进程的数据,有的数据不允许两个线程同时操作,所此时需要加线程锁

import threading
import time

def run(n):
    global num
    lock.acquire() # 申请线程锁
    num += 1
    time.sleep(1)
    lock.release() # 释放线程锁

lock = threading.Lock()

num = 0

t_objs = []
start_time = time.time()
for i in range(5):
    t = threading.Thread(target=run, args=("t-%s" %i,))
    t.start()
    t_objs.append(t)

for i in t_objs:  # 循环所有线程列表,等待所有线程执行完毕
    i.join()

print("all threads have finished!")
print("num:", num)

Event对象

用于线程间通信,即程序中的其一个线程需要通过判断某个线程的状态来确定自己下一步的操作,就用到了event对象

import threading
import time

event = threading.Event()
def lighter():
    count = 0
    event.set()
    while True:
        if count>5 and count<10:
            event.clear()
            print("红灯")
        elif count>10:
            event.set()
            print("绿灯")
            count = 0
        else:
            print("绿灯可以行驶")
        time.sleep(1)
        count += 1

def car(name):
    while True:
        if event.is_set():
            print("汽车[%s]在行驶" % name)
            time.sleep(1)
        else:
            print("看到红灯,等待中")
            event.wait()
            print("红灯结束,开始行驶")

light = threading.Thread(target=lighter)
light.start()

for i in range(3):
    t = threading.Thread(target=car, args=(i,))
    t.start()

事件(Event)

事件是一个简单的同步对象;
事件表示内部标志和线程
可以等待设置标志,也可以自己设置或清除标志。

import threading
import time

event = threading.Event()
def lighter():
    count = 0
    event.set()
    while True:
        if count>5 and count<10:
            event.clear()
            print("红灯")
        elif count>10:
            event.set()
            print("绿灯")
            count = 0
        else:
            print("绿灯可以行驶")
        time.sleep(1)
        count += 1

def car(name):
    while True:
        if event.is_set():
            print("汽车[%s]在行驶" % name)
            time.sleep(1)
        else:
            print("看到红灯,等待中")
            event.wait()
            print("红灯结束,开始行驶")

light = threading.Thread(target=lighter)
light.start()

for i in range(3):
    t = threading.Thread(target=car, args=(i,))
    t.start()

上一篇下一篇

猜你喜欢

热点阅读