python函数锁 python加锁的方法
Python中级精华-临界区加锁
概念梳理:
让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:申请域名、雅安服务器托管、营销软件、网站建设、呼中网站维护、网站推广。
临界区:
临界区指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段
,而这些共用资源又无法同时被多个线程访问的特性。当有线程进入临界区段时,其他线程或是进程必须等待,有一些同步的机制必须在临界区段的进入点与离开点实现,以确保这些共用资源是被互斥获得使用。
目的:
我们在多线程
处理是,经常会涉及到对于一块共享资源的访问,这里就需要线程可以互斥去避免出现竞态条件(race condition).
方法:
要想让可变对象安全地在多线程环境中进行访问,就要使用锁变量(threading中的LockRLock),锁变量也是同步原语
中的最常见一种之一。
示例:
线程的调度从本质上来说是非确定性的(只能保证独一访问,但保证不了谁先谁后)。只要共享的可变状态需要被多个线程访问,就要使用锁机制,保证数据的安全。
在threading库中我们也发现了其他的同步原语例如:RLock(可重入锁)、Semaphore对象(信号量)。
RLock:可以被同一个线程多次获取,主要用来编写基于锁的代码,或者基于‘监听器’的同步处理。
当某个类持有这种类型锁时,只有一个线程可以使用类中全部函数或者方法,例如:
这份代码中只有一个作用于整个类的锁,它被所有的类实例所共享,不再将所绑定在某个实例的可变状态上,现在这个锁是用来同步类中的方法的。对于其他标准锁不同的是,对于已经持有了该锁的方法可以调用同样使用了这个锁的其他方法(参考sub_one())。
这个实现的特点是,无论创建了多少counter实例,这些实例共有同一把锁。因此,当有大量counter出现时,这种方法堆内存的使用效率要高很多。但是可能存在的缺点是在使用了大量线程且需要频繁更新counter中的数据时,这么做会出现锁争用的情况。
另外一种同步原语semaphore,是一种基于共享计数器的同步原语。如果计数器非0,那么with语句会递减计数器并且允许线程继续执行。当with语句块结束后,会将计数器递增。如果计数器为0,那么执行过程会被阻塞,直到由另外一个线程来递增计数器为止。由于信号量
的实现更为复杂,这会对程序带来一定的负面影响。除了简单地加锁功能外,信号量对象对于那些设计在线程间发送信号或者需要实现节流处理的应用中更加有用,例如限制并发总数:
python多线程全局变量和锁
1.python中数据类型,int,float,复数,字符,元组,做全局变量时需要在函数里面用global申明变量,才能对变量进行操作。
而,对象,列表,词典,不需要声明,直接就是全局的。
2.线程锁mutex=threading.Lock()
创建后就是全局的。线程调用函数可以直接在函数中使用。
mutex.acquire()开启锁
mutex=release()关闭锁
要注意,死锁的情况发生。
注意运行效率的变化:
正常1秒,完成56997921
加锁之后,1秒只运行了531187,相差10倍多。
3.继承.threading.Thread的类,无法调用__init__函数,无法在创建对象时初始化新建的属性。
4.线程在cpu的执行,有随机性
5. 新建线程时,需要传参数时,args是一个元组,如果只有一个参数,一定后面要加一个,符号。不能只有一个参数否则线程会报创建参数错误。threading.Thread(target=fuc,args=(arg,))
下面这段python的多线程代码为什么运行不起来,说是函数没有加锁的属性
下面的代码可以,因为你那个lock是变量又是函数,会冲突的,另外,你这个实验其实测试不出来lock属性,因为你调用实际上是顺序的
import string,socket,time,os,sys,threading
num=0
class xThread():
def __init__(self):
self._lock=threading.Lock()
def lock(self):
self._lock.acquire()
def unlock(self):
self._lock.release()
def p2(a):
global num
thread.lock()
num+=1
print(a+str(num))
time.sleep(0.1)
thread.unlock()
def p1(a):
for i in range(3):
info='this %s thread'%(i)
p2(info)
def main():
for i in range(3):
p1(i)
if __name__ == '__main__':
thread=xThread()
main()
浅谈Python中的线程锁
竞争条件 是并发编程中的一个重要问题。当一个线程试图修改共享资源 的同时, 另一个线程正在修改该资源时,就会出现这种情况——这会导致输出乱码,这就是线程需要同步的原因。
Python的threading模块包括 Lock 作为同步工具。锁有两种状态:
可以使用该acquire()方法锁定锁。一旦一个线程获得了锁,所有后续的获取锁的尝试都会被阻塞,直到它被释放。可以使用该release()方法释放锁。
以下代码通过一个简单的示例展示了如何在 Python 中使用锁:
假设银行账户中有 100 美元。每个月存入 10 美元作为利润,扣除 10 美元支付账单。thread1用于存入利润,而thread2用于支付账单。在某些月份,利润会在账单支付后存入。但是,这不应影响帐户中的最终金额。
由于 竞争条件下 ,以下代码得到的结果可能不正确。可能会出现一个线程在上下文切换前无法将更新后的值写入共享变量deposit,而另一个线程读取到未更新的值的情况;因此,导致不可预测的结果。
运行以上代码,将输出
acquire()和release()方法之间的代码是 原子 执行的,因此在另一个线程已经进行更改之后,一个线程不可能读取未更新的版本。
运行以上程序,将输出:
python log 文件锁判断是否有锁
Python的文件锁目前使用的是fcntl这个库,它实际上为 Unix上的ioctl,flock和fcntl 函数提供了一个接口。
1.fcntl库的简单使用
[python] view plain copy
import fcntl
import os, time
FILE = "counter.txt"
if not os.path.exists(FILE):
# create the counter file if it doesn't exist
file = open(FILE, "w")
file.write("0")
file.close()
for i in range(20):
file = open(FILE, "r+") #由于flock生成的是劝告锁,不能阻止进程对文件的操作,所以这里可以正常打开文件
fcntl.flock(file.fileno(), fcntl.LOCK_EX) #为了避免同时操作文件,需要程序自己来检查该文件是否已经被加锁。这里如果检查到加锁了,进程会被阻塞
print 'acquire lock'
counter = int(file.readline()) + 1
file.seek(0)
file.write(str(counter))
print os.getpid(), "=", counter
time.sleep(10)
file.close() # unlocks the file
print 'release lock'
time.sleep(3)
分别启动2个进程来同时运行这个脚本,我们可以很明显的看到2者互相之间交替阻塞。同一时刻只有一个进程能够对counter.txt文件进行操作。
2.对fcntl.flock()函数的说明:
linux的flock() 的函数原型如下所示:
int flock(int fd, int operation);
其中,参数 fd 表示文件描述符;参数 operation 指定要进行的锁操作,该参数的取值有如下几种:
LOCK_SH:表示要创建一个共享锁,在任意时间内,一个文件的共享锁可以被多个进程拥有;
LOCK_EX:表示创建一个排他锁,在任意时间内,一个文件的排他锁只能被一个进程拥有;
LOCK_UN:表示删除该进程创建的锁;
LOCK_MAND:它主要是用于共享模式强制锁,它可以与 LOCK_READ 或者 LOCK_WRITE联合起来使用,从而表示是否允许并发的读操作或者并发的写操作;
通常情况下,如果加锁请求不能被立即满足,那么系统调用 flock()会阻塞当前进程。比如,进程想要请求一个排他锁,但此时,已经由其他进程获取了这个锁,那么该进程将会被阻塞。如果想要在没有获得这个排他锁的情况下不阻塞该进程,可以将LOCK_NB 和 LOCK_SH 或者 LOCK_EX 联合使用,那么系统就不会阻塞该进程。flock()所加的锁会对整个文件起作用。
注意:
1. 对于文件的 close() 操作会使文件锁失效;
2. 同理,进程结束后文件锁失效;
3. flock() 的 LOCK_EX是“劝告锁”,系统内核不会强制检查锁的状态,需要在代码中进行文件操作的地方显式检查才能生效。
分享题目:python函数锁 python加锁的方法
分享地址:http://azwzsj.com/article/hihhdh.html