Python并发编程:多线程-信号量,Event,定时器

一 信号量

  信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行,信号量同一时间可以有5个任务拿到锁去执行,如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群路人争抢公共厕所,公共厕所所有多个坑位,这意味着同一时间可以有多个人上公共厕所,但公共厕所容纳的人数是一定的,这便是信号量的大小

from threading import Thread, Semaphore
import threading
import time

def func():
    sm.acquire()
    print(‘%s get sm‘ % threading.current_thread().getName())
    time.sleep(3)
    sm.release()

if __name__ == ‘__main__‘:
    sm = Semaphore(5)
    for i in range(23):
        t = Thread(target=func)
        t.start()

  解析

Semaphore管理一个内置的计数器,
每当调用acquire()时内置计数器-1
调用release()时内置计数器+1
计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其它线程调用rel()

  

二、Event

线程的一个关键特性是每个线程都是独立运行且状态不可预测。如果程序中的其它线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就会变得非常棘手。为了解决这些问题,我们需要使用threading库中的Event对象。对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。在初始情况下,Event对象中的信号标志被设置为假。如果有线程等待一个Event对象,而这个Event对象的标志为假,那么这个线程将会被一直阻塞至标志为真。一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。如果一个线程等待一个已经被设置为真的Event对象,它将忽略这个事件,继续执行

from threading import Event
Event.isSet()   # 返回Event的状态值
Event.wait()    # 如果event.isSet()==False将阻塞线程;
Event.set()     # 设置Event的状态值为True,所有阻塞池的线程激活进入就绪状态,等待操作系统调度
Event.clear()   # 恢复Event的状态值为False

 

 例如:有多个工作线程尝试链接MySQL,我们想要在链接前确保MySQL服务正常才让那些工作线程去连接MySQL服务器,如果连接不成功,都会去尝试重新连接。那么

from threading import Thread, Event
import threading
import time, random
def conn_mysql():
    count = 1
    while not event.is_set():
        if count > 3:
            raise TimeoutError(‘链接超时‘)
        print(‘<%s>第%s次尝试链接‘ % (threading.current_thread().getName(), count))
        event.wait(0.5)
        count += 1
    print(‘<%s>链接成功‘ % threading.current_thread().getName())

def check_mysql():
    print(‘\033[45m[%s] 正在检查mysql\033[0m‘ % threading.current_thread().getName())
    time.sleep(random.randint(2, 4))
    event.set()

if __name__ == ‘__main__‘:
    event = Event()
    conn1 = Thread(target=conn_mysql)
    conn2 = Thread(target=conn_mysql)
    check = Thread(target=check_mysql)

    conn1.start()
    conn2.start()
    check.start()

  

三 定时器

定时器,指定n秒后执行某操作

from threading import Timer

def hello():

    print(‘hello, world‘)

t = Timer(1, hello)
t.start()

  

原文地址:https://www.cnblogs.com/mike-liu/p/9295914.html

时间: 2024-10-07 19:13:23

Python并发编程:多线程-信号量,Event,定时器的相关文章

python并发编程&amp;多线程(二)

前导理论知识见:python并发编程&多线程(一) 一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性 官网链接:https://docs.python.org/3/library/threading.html?highlight=threading#(装B模式加载中…………) 二 开启线程的两种方式  方式一  方式二 三 在一个进程下开启多个线程与在一个进程下开启多个子进程的区别  1 谁的开启速度快  2 瞅

python并发编程&amp;多线程(一)

本篇理论居多,实际操作见:  python并发编程&多线程(二) 一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合到一起,是一个资源单位,而一个车间内至少有一个流水线 流水线的工作需要电源,电源就相当于cpu 所以,进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位. 多线程(即多个控制线程)的概念

python并发编程--多线程2

并发编程--多线程2 实战部分: threading模块介绍 开启线程的两种方式 在一个进程下开启多个线程与在一个进程下开启多个子进程的区别 练习 线程相关的其他方法 守护线程 python GIL(Global Interpreter Lock) 同步锁 死锁现象与递归锁 信号量Semaphore Evect 条件Condition 定时器 线程queue python标准模块-concurrent.futures 一.threading模块介绍 说明:threading用于提供线程相关的操作

python 并发编程 多线程 GIL全局解释器锁基本概念

首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念. 就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码. >有名的编译器例如GCC,INTEL C++,Visual C++等.Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行. 像其中的JPython就没有GIL.然而因为CPython是大部分环境下默认的Python执行环境.所以在很多人的概

python 并发编程 锁 / 信号量 / 事件 / 队列(进程间通信(IPC)) /生产者消费者模式

(1)锁:进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 虽然使用加锁的形式实现了顺序的执行,但是程序又重新变成串行了,这样确实会浪费了时间,却保证了数据的安全. (Lock) import json from multiprocessing import Process,Lock ###### 锁 ###### import time import random def get

python网络编程--管道,信号量,Event,进程池,回调函数

1.管道 加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行任务修改,即串行修改,速度慢了,但牺牲了速度却保证了数据安全. 文件共享数据实现进程间的通信,但问题是: 1.效率低(共享数据基于文件,而文件是硬盘上的数据) 2.需要自己加锁处理 而使用multiprocess模块为我们提供的基于消息IPC通信机制:通信和管道 可以帮我们解决这两个问题. 队列和管道都是将数据存放于内存内,而队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来来,因而队列才是进程间通信的

python 并发编程 多线程 守护线程

做完工作这个进程就应该被销毁 单线程情况: 一个进程 ,默认有一个主线程 ,这个主线程执行完代码后 ,就应该自动销毁.然后进程也销毁. 多线程情况: 主线程代表进程结束 一个进程可以开多个线程,默认开启进程 ,首先开一个主线程 ,然后开子线程 ,主线程代码执行完毕后 ,也要等所有子线程 ,执行完毕后 ,再销毁 ,然后到进程销毁. 守护进程 要等主进程挂了后 守护进程才挂 1.对主进程来说,运行完毕指的是主进程代码运行完毕 2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完

python 并发编程 多线程 死锁现象与递归锁

一 死锁现象 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁 from threading import Thread from threading import Lock import time # 实例化两把不同的锁 mutexA = Lock() mutexB = Lock() class MyThread(Threa

python-学习-python并发编程之多进程与多线程

一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程.Python提供了multiprocessing.    multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似.  multiprocessing模块的功能众多:支持子进程.通信和共享数据.执行不同形式的同步,

Python并发编程系列之多线程

1引言 2 创建线程 2.1 函数的方式创建线程 2.2 类的方式创建线程 3 Thread类的常用属性和方法 3.1 守护线程:Deamon 3.2 join()方法 4 线程间的同步机制 4.1 互斥锁:Lock 4.2 递归锁:RLock 4.3 Condition 4.4 信号量:Semaphore 4.5 事件:Event 4.6 定时器:Timer 5 线程间的通行 5.1队列:Queue 6 线程池 7 总结 1 引言 上一篇博文详细总结了Python进程的用法,这一篇博文来所以说