python之路---并发编程之线程&守护线程/线程互斥锁/信号量

守护线程

两个关键词:守护/线程

守护:伴随,线程:本质也是一种线程

守护线程会随着该进程内的所有非守护线程结束而结束。即,守护线程是守护着整个进程的运行周期

怎么用

和开启守护进程的方式一样,在start()之前设置daemon=True

import time
from threading import Thread


def foo(name):
    print('%s is running' % name)
    # time.sleep(1)
    time.sleep(3)
    print('123')


def bar(name):
    print('%s is running' % name)
    time.sleep(1)
    print('%s is done' % name)


t1 = Thread(target=foo, args=('守护线程',))
t2 = Thread(target=bar, args=('子线程',))
t1.daemon = True
t1.start()
t2.start()

print('主')

#运行结果
守护线程 is running
子线程 is running
主
子线程 is done

从运行结果可以看出,守护线程伴随着子进程的结束而结束,并没有运行后面的代码

互斥锁

互斥锁的作用是使多个任务对共享数据的操作由并发变为“串行”,虽然牺牲了效率,但是保证了数据的安全

没有互斥锁的情况下:

import time
from threading import Thread, Lock

lock_obj = Lock()

x = 1000
l = []


def task():
    global x
    temp = x-1
    time.sleep(0.1) # 由于起线程的速度太快,要加上这句,模拟多个并发线程对共享数据的修改
    x = temp

start = time.time()
for i in range(300):
    thread = Thread(target=task)
    l.append(thread)
    thread.start()

for t in l:
    t.join()
end = time.time()
print('主', x, end - start)

 有互斥锁的情况下

import time
from threading import Thread, Lock

lock_obj = Lock()

x = 1000
l = []


def task():
    global x
    with lock_obj:
        temp = x-1
        time.sleep(0.01)
        x = temp


start = time.time()
for i in range(300):
    thread = Thread(target=task)
    l.append(thread)
    thread.start()

for t in l:
    t.join()
end = time.time()
print('主', x, end - start)

信号量

控制同一时刻并发执行的任务数

import time, random
from threading import Thread, current_thread, Semaphore

sm = Semaphore(5)


def task():
    with sm:
        print('%s:正在上厕所...' % current_thread().name)
        time.sleep(random.uniform(1, 3))
    print('%s:出厕所' % current_thread().name)


if __name__ == '__main__':
    for i in range(20):
        obj = Thread(target=task)
        obj.start()

猜你喜欢

转载自blog.csdn.net/ltfdsy/article/details/82460773