8.19_python_lx_day34

一.Manager (list 列表 , dict 字典) 进程之间的共享数据(列表或者字典等)

from multiprocessing import Process,Manager,Lock

(1) 基本语法

def work(data,lcok):
    # 1.正常写法
    '''
    #上锁
    lock.acquire()
    # 修改数据
    dic['count'] -=1
    # 解锁
    lock.release()
    '''
    # 2.使用with语法可以简化上锁和解锁两步操作
    with lock:
        data[0]+=1
if __name__=='__main__':
    lst=[]
    lock = Lock()
    m = Manager()
    data = m.dict( {'count':2000 } )
    data = m.list( [1,2,3] )
    for i in range(50):
        p = Process(target=work,args=(data,lock))
        p.stat()
        lst.append(p)
    # 确保所有程序执行完毕之后,再向下执行,打印数据,否则报错.
    for i in lst:
        i.join()
    print(data)

二.线程

  • 进程:资源分配的最小单位
  • 线程:cpu执行程序的最小单位
from threading import Thread
from multiprocessing import  Process
import os,time,random

(1) 一个进程资源中可以包含多个线程

def func(num):
    time.sleep(random.uniform(0.1,1))
    print("当前进程{},参数是{}".format(os.getpid(),num))
for i in range(10):
    t = Thread(target=func,args=(i,))
    t.start()
print(os.getpid())

(2) 并发的多线程和多进程谁的速度快? 多线程!

 <1>并发的多线程

def func(num):
    print('当前进程{},参数是{}'.format(os.getpid(),num))
if __name__=='__main__':
    lst = []
    # 记录开始时间
    startime = time.time()
    for i in range(1000):
        t = Thread(target=func,args=(i,))
        t.start()
        lst.append(t)
    #等待所有子线程执行完毕
    for i in lst:
        i.join()
    # 计算结束时间
    endtime  = time.time()
    print('多线程执行时间',(endtime-starttime))

<2>并发的多进程

def func():
    print('当前进程{},参数是{}'.format(os.getpid(),num))
if __name__ =='__main__':
    lst = []
    # 记录开始时间
    starttime = time.time()
    for i in range(1000):
        p = Process(target=func,args=(i,))
        p.start()
        lst.appen(p)
    # 等到所有的子进程执行完毕
    for i in lst:
        i.join()
    # 计算结束时间
    endtime = time.time()
    print('多进程执行时间',(endtime-starttime))

<3>多线程之间,共享同一份进程资源

num = 1000
def func():
    global num
    num -=1
for i in range(1000):
    t = Thread(target=func)
    t.start()
print(num)

三.用类定义线程

from threading import Thread,
import os,time

(1)基本语法:

class MyThread(Thread):
    def __init__(self,name):
        # 手动调用父类方法
        super().__init__()
        self.name = name
    def run(self):
        time.sleep(1)
        print('当前进程号码是{},名字是{}'.format(os.getpid(),self.name))
if __name__=='__main__':
    t = MyThread('当时是一个线程')
    t.start()
    print('主线程运行结束 ... ')

四.线程的相关函数

  • 线程.is_alive()   检测线程是否仍然存在
  • 线程.setName()    设置线程名字
  • 线程.getName()    获取线程名字
  • 1.currentThread().ident    查看线程id号
  • 2.enumerate()    返回目前正在运行的线程列表
  • 3.activeCount()    返回目前正在运行的线程数量
def func():
    time.sleep(1)
if __name__=='__main__':
    t = Thread(target=func)
    t.start()
    # 检测线程是否仍然存在
    print(t.is_alive())
    # 获取线程名字
    print(t.getName()) # Thread-1
    # 设置线程名字
    t.setName('lx')
    # 获取线程名字
    print(t.getName())

(1)currentThread)().ident  查看线程id号

from threading import currentThread
# 1.currentThread().ident    查看线程id号
def func():
    print('子线程的线程id{}'.format(currentThread().ident))
if __name__ =='__main__':
    Thread(target=func).start()
    print('主线程的线程id{}'.format(currentThread().ident))

(2)enumerate() 返回目前正在运行的线程列表
(3)activeCount() 返回目前正在运行的线程数量(了解)

from threading import enumerate
from threading import activeCount
def func():
    print('子线程的线程id{}'.format(currentThread()ident))
    time.sleep(0.5)
if __name__=='__main__':
    for i in range(10):
        Thread(target=func).start()
    lst = enumerate()
    # 主线程 + 10个子线程
    print(lst,len(lst))
    # 3.activeCount()返回目前正在运行的线程数量
    print(activeCount())

五.守护线程

  • 守护线程:等待所有线程全部执行完毕之后,自己在终止,守护所有线程
from threading import Thread
import time
def func1:
    while True :
        time.sleep(0.5)
        print('func1')
def func2():
    print('我是func2 start ... ')
    time.sleep(3)
    print('我是func2 end ... ')
def func3():
    print('我是func3 start ... ')
    time.sleep(5)
    print('我是func3 end ... ')
if __name__=='__main__':
    t1 = Thread(target=func1)
    t2 = Thread(target=func2)
    t3 = Thread(target=func3)
    # 在start调用之前,设置线程为守护线程
    t1.setDaemon(True)
    t1.start()
    t2.start()
    t3.start()
    print('主线程序结束 ... ')

六.线程中安全问题 Lock

from threading import Lock,Thread
import time
n = 0
def func(lock):
    global n
    lock.acquire()
    for i in range(1000000):
        n += 1
    lock.release()
def func2(lock):
    global n
    # with 自动完成上锁+解锁
    with lock:
        for i in range(1000000):
            n -= 1
if __name__=='__main__':
    lst = []
    lcok = Lock()
    startime = time.time()
    for i in range(10):
        t1 = Thread(target=func1,args=(lock,))
        t2 = Thread(target=func2,args=(lock,))
        t1.start()
        t2.start()
        lst.append(t1)
        lst.append(t2)
    for i in lst:
        i.join()
    endtime = time.time()
    print('主线程执行结束 ... 打印{}时间是{}'.format(n,endtime-startime))

七.信号量 Semaphore(线程)

from threading import Semaphore,Thread
import time
def func(i,sm):
    # 上锁 + 解锁
    with sm:
        print(i)
        time.sleep(3)
if __name__=='__main__':
    # 支持同一时间,5 个线程上锁
    sm = Semaphore(5)
    for i in range(20):
        Thread(target=func,args=(i,sm)).start()
  • 再创建线程的时候是异步创建
  • 在执行任务时,遇到Semaphore进行上锁,会编程同步程序
原文地址:https://www.cnblogs.com/Magicianlx/p/13531684.html