多线程&python(note实战笔记)

2020-10-13  本文已影响0人  Luy_

一.理论知识

What is 进程

什么是线程

So,Python与线程是什么关系

GIL!?

GIL保证一个线程

二.实战

python的两种线程管理

实战笔记

from time import sleep, ctime

import logging
import _thread
'''
@author: Luy
@data:2020-10-12 13:15
@Summary:_thread的使用与理解

'''
#设置日志级别。
logging.basicConfig(level=logging.INFO)

def loop0():
    logging.info("start loop0 at " + ctime())
    sleep(4)
    logging.info("end loop0 at " + ctime())

def loop1():
    logging.info("start loop1 at " + ctime())
    sleep(2)
    logging.info("end loop1 at " + ctime())

def main():
   
    logging.info("start all at " + ctime())
    _thread.start_new_thread(loop0, ())
    _thread.start_new_thread(loop1, ()) 
    #这里加sleep(6)的原因
    #_thread当主线程退出之后,所有的子线程都会被kill掉(没有守护线程的概念)
    sleep(6)
    logging.info("end all at " + ctime())

if __name__ == '__main__':
    main()

*_thread不守护线程,当主线程退出之后,所有的子线程都会被kill掉,所以需要加sleep来进行等待,确保子进程顺利执行

'''
@author: Luy
@data:2020-10-12 13:15
@Summary:_thread的锁操作

'''

from time import sleep, ctime

import logging
import _thread

logging.basicConfig(level=logging.INFO)

loops = [2, 4]

'''
nloop-用于标识当前loop属于第几个
nsec-时间,告诉我们这个循环了多长的时间
lock-传进来的锁,首先,会传进来一个锁住的锁,当我们loop执行结束后子线程都会进行解锁,当判断到所有的线程都解锁了,此时主进程就可以结束了
'''
def loop(nloop, nsec, lock):
    logging.info("start loops" + str(nloop) + " at " + ctime())
    #传一个动态时间
    sleep(nsec)
    logging.info("end loops " + str(nloop) + "at " + ctime())
    #对锁进行一个释放
    lock.release()


def main():

    logging.info("start all at " + ctime())
    #声明一个锁的list
    locks = []
    nloops = range(len(loops))

    for i in nloops:
        #取出之后我们声明一个新的锁lock
        lock = _thread.allocate_lock()
        #上锁
        lock.acquire()
        #加锁之后传递给locks
        locks.append(lock)
    # 执行子线程和加锁操作分开写的原因,获取锁的操作是需要时间的,很有可能会出现,当获取锁的时候,开启一个新的子线程,而我在获取第二个锁的时候子线程已经执行完毕了,然后出现一个解锁的操作,主线程就退出了
    # 当执行第一循环执行获取一个锁的时候,执行子程序,当第二个循环获取第二个锁的时候慢于第一个子线程的执行速度,那第一个就回去进行一个解锁操作,程序就停下来了

    #起线程用的循环
    for i in nloops:
        #起一个子线程,每开启一个
        _thread.start_new_thread(loop, (i, loops[i], locks[i]))

    #主线程。依次取出两个线程,然后判断锁是不是解锁的,如果解锁了,就结束线程
    for i in nloops:
        while locks[i].locked(): pass

    logging.info("end all at " + ctime())


if __name__ == '__main__':
    main()

使用threading实现上面的内容

from time import sleep, ctime

import logging
import _thread
import threading

logging.basicConfig(level=logging.INFO)

loops = [2, 4]


def loop(nloop, nsec):
    logging.info("start loops" + str(nloop) + " at " + ctime())
    sleep(nsec)
    logging.info("end loops " + str(nloop) + "at " + ctime())

def main():


    logging.info("start all at " + ctime())
    threads = []
    nloops = range(len(loops))


    for i in nloops:
        t = threading.Thread(target=loop, args=(i, loops[i]))
        threads.append(t)
    for i in nloops:
        threads[i].start()
    for i in nloops:
        #等待线程是否执行完毕,如果是未完成,则堵塞在这里
        threads[i].join()

    logging.info("end all at " + ctime())


if __name__ == '__main__':
    main()

面向对象的多线程写法

from time import sleep, ctime

import logging
import _thread
import threading


##面向对象的写法
#原语
##锁
##信号量
##

logging.basicConfig(level=logging.INFO)

loops = [2, 4]

#创建一个类继承threading的Thread方法,
class MyThread(threading.Thread):
    #1.主动调用Thread的初始构造方法,把其他传进来的参数,存到类中
    def __init__(self, func, args, name=''):
        threading.Thread.__init__(self)
        self.func =func
        self.args = args
        self.name =name
    #2.重写方法
    def run(self):
        self.func(*self.args)


def loop(nloop, nsec):
    logging.info("start loops" + str(nloop) + " at " + ctime())
    sleep(nsec)
    logging.info("end loops " + str(nloop) + "at " + ctime())

def main():

    logging.info("start all at " + ctime())
    threads = []
    nloops = range(len(loops))


    for i in nloops:
        t = MyThread(loop,(i, loops[i]), loop.__name__)
        threads.append(t)
    for i in nloops:
        threads[i].start()
    for i in nloops:
        threads[i].join()

    logging.info("end all at " + ctime())


if __name__ == '__main__':
    main()

上一篇 下一篇

猜你喜欢

热点阅读