Python连载33-共享变量加锁、释放

一、共享变量

共享变量:当多个线程访问同一个变量的时候。会产生共享变量的问题。

例子:

import threading

sum = 0

loopSum = 1000000

def myAdd():

    global sum, loopSum

    for i in range(1,loopSum):

        sum += 1

def myMinu():

    global sum, loopSum

    for i in range(1,loopSum):

        sum -= 1

if __name__ == "__main__":

    print("Dont,,,,,,,{0}".format(sum))

    t1 = threading.Thread(target=myAdd,args=())

    t2 = threading.Thread(target=myMinu,args=())

    t1.start()

    t2.start()

    t1.join()

    t2.join()

    print("Done,,,,,,{0}".format(sum))

正如上面的结果可以看出:并不是我们期望的0,而是-286705,这就是因为我们共享变量了,同时对变量进行了操作,程序并不是原子的。

2.解决方案:使用“锁”,“信号灯”

(1)锁lock:是一个标志,表示一个线程在占用一些资源。

使用方式:先上锁,然后使用共享资源,放心的使用,最后再释放锁,即释放了这个变量。

锁哪个:哪个资源需要共享,那么就锁谁

import threading

sum = 0

loopSum = 1000000

lock = threading.Lock()

#先生成一个锁的实例

def myAdd():

    global sum, loopSum

    for i in range(1,loopSum):

        lock.acquire()#这里申请了一把锁

        sum += 1

        lock.release()#注意千万不要忘了释放锁

def myMinu():

    global sum, loopSum

    for i in range(1,loopSum):

        lock.acquire()

        sum -= 1

        lock.release()

if __name__ == "__main__":

    print("Done,,,,,,,{0}".format(sum))

    t1 = threading.Thread(target=myAdd,args=())

    t2 = threading.Thread(target=myMinu,args=())

    t1.start()

    t2.start()

    t1.join()

    t2.join()

    print("Done,,,,,,{0}".format(sum))

正如我们所预料的加减的顺序无所谓,但最后是零和游戏,但是上面的那个例子,都也是加减顺序无所谓,但是有一点要知道会存在同时对变量的内存使用的情况,这就存在内存被错写的风险,所以最后结果不对,上面的不是零和游戏。

(2)线程的安全问题:

如果一个资源、变量,他对于多线程来讲,不用加锁,也不会引起任何问题,则称为线程安全;线程不安全的变量类型:list\set\dict;线程安全的变量类型:queue

二、源码

d25_1_shared_variable_and_lock.py

https://github.com/ruigege66/Python_learning/blob/master/d25_1_shared_variable_and_lock.py

2.CSDN:https://blog.csdn.net/weixin_44630050(心悦君兮君不知-睿)

3.博客园:https://www.cnblogs.com/ruigege0000/

4.欢迎关注微信公众号:傅里叶变换,后台回复”礼包“,获取大数据学习资料

原文地址:https://www.cnblogs.com/ruigege0000/p/11421552.html

时间: 2024-10-16 22:01:57

Python连载33-共享变量加锁、释放的相关文章

Python连载59-HTTP首部字段和消息头,Thinker简介

一.首部字段或者消息头 1.下面几个类型都是请求的: User-Agent:关于浏览器和它平台的消息,如Mozilla5.0 Accept:客户端能处理的页面的类型,如text/html Accept-Charset:客户端可以接受的字符集,如unicode-1-1 Accept-Encoding:客户端能处理的页面编码方式,如gzip Accept-Language:客户端能处理的自然语言,如en(英语).zh-en(简体中文) Host:服务器的DNS名称,从URL中提取出来,必需 Auth

『Python』 多线程 共享变量的实现

简介: 对于Python2而言,对于一个全局变量,你的函数里如果只使用到了它的值,而没有对其赋值(指a = XXX这种写法)的话,就不需要声明global. 相反,如果你对其赋了值的话,那么你就需要声明global. 声明global的话,就表示你是在向一个全局变量赋值,而不是在向一个局部变量赋值. 若多个线程或进程同时操作这一变量可能会导致抢占资源的现象,变量不能按照预定的逻辑进行操作,这时,在改变变量前需要对变量加互斥锁,操作完成后释放互斥锁. 题外话: GIL(Global Interpr

python(33)多进程和多线程的区别

多线程可以共享全局变量,多进程不能.多线程中,所有子线程的进程号相同:多进程中,不同的子进程进程号不同. #!/usr/bin/python # -*- coding:utf-8 -*- import os import threading import multiprocessing count_thread = 0 count_process = 0 # worker function def worker1(sign, lock): global count_thread lock.acq

Python中给文件加锁

首先要引入库import fcntl打开一个文件f = open('./test')对该文件加密:fcntl.flock(f, fcntl.LOCK_EX)这样就对文件test加锁了,如果有其他进程要对test进行加锁,则不能成功,会被阻塞,但不会退出程序.解锁:fcntl.flock(f,fcntl.LOCK_UN)解锁后,其他进程就可以对该文件进行加锁了.另外还有一种共享锁:acquire a shared lockfcntl.flock(f,fcntl.LOCK_SH) 还有一篇文章htt

Python连载7-time包的其他函数

接连载6 一.time包 1.函数:sleep(second) (1)含义:是程序进入休眠状态多少秒 (2)格式:time.sleep(int num) 2.函数:strftime() (1)含义:将我们的时间戳表示成我们想要的时间格式 (2)格式:time.strftime(时间戳) (3)返回值类型:字符串 (4)字符含义: %y 两位数的年份表示(00-99) %Y 四位数的年份表示(000-9999) %m 月份(01-12) %d 月内中的一天(0-31) %H 24小时制小时数(0-

Python连载8-datetime包函数介绍

一.datetime包(上接连载7内容) 1.函数:datetime (1)用法:输入一个日期,来返回一个datetime类? (2)格式:datetime.datetime(年,月,日,hour=,minute=,second=) 其中hour,minute,second可选 (3)附加类方法: today():返回本地当前时间 now():返回本地当前时间 utcnow():返回本地当前时间 fromtimestamp(时间戳):返回时间戳的本地时间 dt = datetime.dateti

Python连载18-closure闭包解释及其注意点

一.闭包 1.定义:当一个函数在内部定义函数,并且内部的函数应用外部函数的参数或者局部变量,当内部函数被当做返回值的时候,相关参数和变量保存在返回的函数之中,这种结果,叫做闭包. 2.例子:连载17中的myF4就是一个典型的例子?. 3.闭包常见的坑 def count(): #定义列表 fs = [] for i in range(1,4): def f(): return i*i fs.append(f) #按照我们的预期,应该是fs=[f,f,f].其中f中一次包含1,4,9,这样才对,但

Python连载19-装饰器

一.检视一个函数相同的另一种方法 利用属性:函数._name def hello(): print("我是一个测试程序") f = hello print(f.__name__) print(hello.__name__) 从结果来看他们的本体都是hello函数 二.装饰器 1.定义:在不改动代码的基础上无限扩展函数功能的一种机制,本质上来讲,装饰器是一个返回函数的高阶函数. 2.装饰器的使用:使用@愈发,即在每次要扩展到函数定义前使用@+函数名. import time #对hell

Python连载23-file_analysis

一.文件 1.定义:长久保存信息的一种信息集合 2.常用操作:(1)打开关闭(2)读写内容(3)查找 3.open函数 (1)意义:打开文件,带有很多参数 (2)第一个参数:必须有,文件的路径和名称 mode:表明文件用什么方式打开 i.r代表只读的方式打开;ii.w:写方式打开,会覆盖以前的内容:iii.x代表创建方式打开,如果文件已经存在,则会报错:iv.a代表append方式以追加的方式对文件内容进行写入:v.b代表binary方式,二进制方式写入:vi.t代表文本的方式打开:vii.+代