代码:

# -*- coding: utf-8 -*-
"""
多线程并发同步 ,使用信号量threading.Semaphore 逻辑:
多个线程,对同一个共享变量 ,加1,并且各自打印加1前、加1后的值
总结:
信号量也提供acquire方法和release方法,每当调用acquire方法的时候,如果内部计数器大于0,则将其减1,
如果内部计数器等于0,则会阻塞该线程,知道有线程调用了release方法将内部计数器更新到大于1位置 1. 个人感觉,信号量类似锁,创建2个大小的信号量,类似创建2把锁
2. 信号量好像可以实现进程Pool,做到任何时候最多有多少个线程执行某些逻辑
3. 使用 信号量,要很小心,可能存在多个线程操作同一份数据 ,导致不一致
比如 case1,case2,case3,case4 使用:
1. 创建指定大小的信号量对象 sem = threading.Semaphore(value=2)
2. 在必要的地方获得信号量,一般是操作共享数据 sem.acquire()
3. 结束的地方,及时释放信号量 sem.release()
参考: """
import threading
import time # 计算pi
def calc_pi():
from sys import stdout
scale = 10000
maxarr = 2800
arrinit = 2000
carry = 0
arr = [arrinit] * (maxarr + 1)
for i in xrange(maxarr, 1, -14):
total = 0
for j in xrange(i, 0,-1):
total = (total * j) + (scale * arr[j])
arr[j] = total % ((j * 2) - 1)
total = total / ((j * 2) - 1)
# stdout.write("%04d" % (carry + (total / scale)))
carry = total % scale # 打印一个字符
def show1():
print "h" # 打印很多字符
def show2():
print "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh" class Num:
"""
多线程操作的共享数据和方法封装
数据 num
方法 add 加1
"""
def __init__(self):
self.num = 0
self.sem = threading.Semaphore(value=2) # 大小=2的信号量 def add(self):
self.sem.acquire() # 获取信号量, 内部计数器-1
begin = self.num # 加1前的值
self.num += 1 # time.sleep(1) # case1 睡眠1秒
# calc_pi() # case2 执行计算密集型运行
# show1() # case3 打印很少字符
# show2() # case4 打印很多字符 end = self.num # 加1后的值
time.sleep(2) # 各个线程睡眠2秒,方便看程序执行效果
self.sem.release() # 释放信号量,内部计数器+1 return (begin,end) # 共享数据
n = Num() class jdThread(threading.Thread):
"""多线程代码,对共享数据加1,并且打印
"""
def __init__(self,item):
threading.Thread.__init__(self)
self.item = item def run(self):
value = n.add() # 加1,拿到返回值 (处理前,处理后)
print "\n", time.strftime('%M:%S',time.localtime(time.time())), " "+str(value[0])+"->"+str(value[1])+" " if __name__ == "__main__": # 启动20个线程
for item in range(20):
t = jdThread(item)
t.start() print "main end"

输出:

基准,以上代码执行

main end

03:58  0->1 

03:58  1->2 

04:00  2->3 

04:00  3->4 

04:02  4->5 

04:02  5->6 

04:04  6->7 

04:04  7->8 

04:06  8->9 

04:06  9->10 

04:08  10->11 

04:08  11->12 

04:10  12->13 

04:10  13->14 

04:12  14->15 

04:12  15->16 

04:14  16->17 

04:14  17->18 

04:16  18->19 

04:16  19->20 

case1,多执行case1

main end

07:48
07:48 1->2->2 07:51
2->4 07:51
3->4 07:54
4->6 07:54
5->6 07:57 6->8 07:57 7->8

case2

main end

08:1808:18   0->2  1->28:21  3->48:21  2->48:23  5->68:23  4->68:26  7->88:26  6->8 

case3

h
h
main end 08:48h
0->1
h 08:48 1->2 h08:50
2->38:50 h 3->48:52h
4->5
h 08:52 5->6 h08:54
6->78:54 h 7->8 h08:56
8->9
h 08:56 9->108:58 h 10->118:58h
11->129:00h
12->139:00 13->14
h
h
09:02
14->159:02 h 15->16 h09:04
16->179:04 h 17->189:06 18->199:06 19->20 Process finished with exit code 0

case4

D:\Programs\Anaconda\python.exe D:/1_practice/python/projects/downloads_modify/归类/并发/thread_sync_2.py
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
main end 10:55 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh 1->2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh10:55->1 10:57hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
2->3 10:57hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
3->4 10:59 4->5 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh10:59hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh 5->6 11:01
7->8 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
11:01
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
6->8 11:03 8->10 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh11:03hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh 9->10 11:05
11->12 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh11:05 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh 10->12 11:07
11:07 12->14 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh 13->14 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh 11:09 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh 14->16 11:09hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh 15->16

输出说明 :

基准输出 , 执行正常的逻辑,每隔2秒执行2个线程,分布对共享变量加1,逻辑正常

case1  睡眠1秒 ,  被其他线程 修改了 数据

case2    计算 密集型,同case1

case3   输出少了 字符 , 逻辑正常

case4   输出大量字符  ,通case1

[b0032] python 归纳 (十七)_线程同步_信号量Semaphore的更多相关文章

  1. [b0034] python 归纳 (十九)_线程同步_条件变量

    代码: # -*- coding: utf-8 -*- """ 学习线程同步,使用条件变量 逻辑: 生产消费者模型 一个有3个大小的产品库,一个生产者负责生产,一个消费者 ...

  2. [b0031] python 归纳 (十六)_线程同步_锁

    # -*- coding: utf-8 -*- """ 学习 多线程同步 使用锁 threading.Lock() 逻辑: 2 个线程,操作同一个整型变量,一个加法,另外 ...

  3. 归纳一下:C#线程同步的几种方法

    转自原文 归纳一下:C#线程同步的几种方法 我们在编程的时候,有时会使用多线程来解决问题,比如你的程序需要在后台处理一大堆数据,但还要使用户界面处于可操作状态:或者你的程序需要访问一些外部资源如数据库 ...

  4. C#当中的多线程_线程同步

    第2章 线程同步 原来以为线程同步就是lock,monitor等呢,看了第二章真是大开眼界啊! 第一章中我们遇到了一个叫做竞争条件的问题.引起的原因是没有进行正确的线程同步.当一个线程在执行操作时候, ...

  5. 零基础逆向工程37_Win32_11_事件_线程同步

    1 内核对象 前面已经学过线程和互斥体两个内核对象.此节讲了事件这个内核对象.前面提出了内核对象这个概念,可能不太清晰,简单来说内核对象就是系统层的东西. 1.1 小结内核对象: 进程.线程.事件.互 ...

  6. java ->多线程_线程同步、死锁、等待唤醒机制

    线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. l  我们通过一个案例,演示线 ...

  7. Python并发编程-进程 线程 同步锁 线程死锁和递归锁

    进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...

  8. Python并行编程(五):线程同步之信号量

    1.基本概念 信号量是由操作系统管理的一种抽象数据类型,用于在多线程中同步对共享资源的使用.本质上说,信号量是一个内部数据,用于标明当前的共享资源可以有多少并发读取. 同样在threading中,信号 ...

  9. 线程同步 –Mutex和Semaphore

    上一篇介绍了同步事件EventWaitHandle,以及它的两个子类型AutoResetEvent和ManualResetEvent.下面接着介绍WaitHandle的另外两个子类型Mutex和Sem ...

随机推荐

  1. JPA连接Mysql数据库时提示:Table 'jpa.sequence' dosen't exisit

    场景 在使用JPA连接Mysql数据库进行数据持久化时提示: Table 'jpa.sequence' dosen't exist 注: 博客主页: https://blog.csdn.net/bad ...

  2. 易优CMS:if的基础用法

    [基础用法] 名称:if 功能:条件判断,比switch判断标签更灵活些,视个人习惯而用. 语法: {eyou:if condition='($eyou.field.has_children > ...

  3. PHP strstr 字符串函数

    定义和用法 strstr - 查找字符串的首次出现 版本支持 PHP4 PHP5 PHP7 支持 支持 支持 V5.3.0 新增可选的 before_needle 参数. V4.3.0 strstr( ...

  4. Java - IO 内存流和打印流

    IO 内存流和打印流操作 字符编码 计算机中所有的信息组成都是二进制数据,所有能够描述的中文文字都是经过处理后的结果:所有的语言文字都会使用编码来进行描述,例如:ASCII码 常见编码 GBK/GB2 ...

  5. 关于Java的多线程Runnable的个人理解(基础,不讲概念)

    背景说明: 在学了Java的多线程(继承Thread,Runnable)以后,我出于好奇,就想知道java到底是不是多线程的,不能它说自己是多线程就是多线程,自己想验证一下,于是我就想测试一下,但继承 ...

  6. 记一次mq无法正常生产消息的事故排查过程

    早上上班后得知,服务费未同步到代理商系统.查看draft_server系统生产环境的log,显示在往RabbitMQ推数据时出现异常:no route to host. 2019-07-29 01:3 ...

  7. 转战物联网·基础篇07-深入理解MQTT协议之控制报文(数据包)格式

      在MQTT协议中,一个控制报文(数据包)的结构按照前后顺序分如下三部分: 结构名 中文名 解释说明 Fixed header 固定报头 报文的最开始部分,所有报文都包含这个部分 Variable ...

  8. 读数笔记_python网络编程3(4)

    4.套接字名与DNS 讨论网络地址,描述将主机名解析为原始IP地址的分布式服务 4.1. 主机名与socket 浏览器汇总一般键入域名.有些域名标识整个机构.如,python.org,而另一些指定了主 ...

  9. AcWing 37. 树的子结构

    题目描述  地址https://www.acwing.com/problem/content/35/输入两棵二叉树A,B,判断B是不是A的子结构. 我们规定空树不是任何树的子结构. 样例 树A: / ...

  10. 从傅里叶变换(FFT)到数论变换(NTT)

    FFT可以用来计算多项式乘法,但是复数的运算中含有大量的浮点数,精度较低.对于只有整数参与运算的多项式,有时,\(\text{NTT(Number-Theoretic Transform)}\)会是更 ...