21天学Python --- 打卡5:Python && Threading

发布于:2022-08-08 ⋅ 阅读:(320) ⋅ 点赞:(0)

在这里插入图片描述

21天学Python --- 打卡5:Python && Threading


在这里插入图片描述

文章摘抄笨小孩: https://blog.csdn.net/weixin_40481076/article/details/101594705.

1.Threading

1.1 什么是线程

  • 线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行

1.2 两者的区别

线程与进程的区别:

  • 线程共享内存,进程独立内存
  • 线程启动速度块,进程启动速度慢,运行时速度没有可比性
  • 同一个进程的线程间可以直接交流,两个进程想通信,必须通过一个中间代理来实现
  • 创建新线程很简单,创建新进程需要对其父进程进行一次克隆
  • 一个线程可以控制和操作同一线程里的其他线程,但是进程只能操作子进程

2.创建线程

python主要是通过thread和threading这两个模块来实现多线程支持。python的thread模块是比较底层的模块,python的threading模块是对thread做了一些封装

2.1 普通创建

def run(n):
    print('task',n)
    time.sleep(1)
    print('2s')
    time.sleep(1)
    print('1s')
    time.sleep(1)
    print('0s')
    time.sleep(1)

if __name__ == '__main__':
    t1 = threading.Thread(target=run,args=('t1',))     # target是要执行的函数名(不是函数),args是函数对应的参数
    t2 = threading.Thread(target=run,args=('t2',))
    t1.start()
    t2.start()

2.2 自定义

class MyThread(threading.Thread):
    def __init__(self,n):
        super(MyThread,self).__init__()   #重构run函数必须写
        self.n = n

    def run(self):
        print('task',self.n)
        time.sleep(1)
        print('2s')
        time.sleep(1)
        print('1s')
        time.sleep(1)
        print('0s')
        time.sleep(1)

if __name__ == '__main__':
    t1 = MyThread('t1')
    t2 = MyThread('t2')
    t1.start()
    t2.start()

2.3 守护线程

def run(n):
    print('task',n)
    time.sleep(1)
    print('3s')
    time.sleep(1)
    print('2s')
    time.sleep(1)
    print('1s')

if __name__ == '__main__':
    t=threading.Thread(target=run,args=('t1',))
    t.setDaemon(True)
    t.start()
    print('end')

2.4 多线程共享全局变量

g_num = 100
def work1():
    global  g_num
    for i in range(3):
        g_num+=1
    print('in work1 g_num is : %d' % g_num)

def work2():
    global g_num
    print('in work2 g_num is : %d' % g_num)

if __name__ == '__main__':
    t1 = threading.Thread(target=work1)
    t1.start()
    time.sleep(1)
    t2=threading.Thread(target=work2)
    t2.start()

2.5 主线程等待子线程结束

def run(n):
    print('task',n)
    time.sleep(2)
    print('5s')
    time.sleep(2)
    print('3s')
    time.sleep(2)
    print('1s')
if __name__ == '__main__':
    t=threading.Thread(target=run,args=('t1',))
    t.setDaemon(True)    #把子线程设置为守护线程,必须在start()之前设置
    t.start()
    t.join()     #设置主线程等待子线程结束
    print('end')

2.6 互斥锁

def work():
    global n
    lock.acquire()
    temp = n
    time.sleep(0.1)
    n = temp-1
    lock.release()


if __name__ == '__main__':
    lock = Lock()
    n = 100
    l = []
    for i in range(100):
        p = Thread(target=work)
        l.append(p)
        p.start()
    for p in l:
        p.join()

2.7 递归锁

def func(lock):
    global gl_num
    lock.acquire()
    gl_num += 1
    time.sleep(1)
    print(gl_num)
    lock.release()


if __name__ == '__main__':
    gl_num = 0
    lock = threading.RLock()
    for i in range(10):
        t = threading.Thread(target=func,args=(lock,))
        t.start()

2.8 信号量

def run(n,semaphore):
    semaphore.acquire()   #加锁
    time.sleep(3)
    print('run the thread:%s\n' % n)
    semaphore.release()    #释放


if __name__== '__main__':
    num=0
    semaphore = threading.BoundedSemaphore(5)   #最多允许5个线程同时运行
    for i in range(22):
        t = threading.Thread(target=run,args=('t-%s' % i,semaphore))
        t.start()
    while threading.active_count() !=1:
        pass
    else:
        print('----------all threads done-----------')

3.线程池

线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。

3.1 实现线程池

#encoding:utf-8
import time
import threadpool
import random
import threading

def sayhello(str):  #执行方法
    sleep_seconds=random.randint(1, 3)
    print '线程名称:%s,参数:%s,睡眠时间:%s'%(threading.current_thread().name,str,sleep_seconds)
    time.sleep(sleep_seconds)

name_list =['aa','bb','cc','dd']    #总共需要执行4个线程
start_time = time.time()    #开始时间
pool = threadpool.ThreadPool(2)     #创建2个线程

requests = threadpool.makeRequests(sayhello, name_list)
for req in requests:
    pool.putRequest(req)    #将每个请求添加到线程池中
pool.wait()  #等待线程执行完后再执行主线程
print '总共运行时间:%d second'% (time.time()-start_time)
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到