相关文章推荐

Python的多线程在io方面比单线程还是有优势,但是在多线程开发时,少不了对文件的读写操作。在管理多个线程对同一文件的读写操作时,就少不了文件锁了。

使用fcntl

在linux下,python的标准库有现成的文件锁,来自于fcntl模块。这个模块提供了unix系统fcntl()和ioctl()的接口。

对于文件锁的操作,主要需要使用 fcntl.flock(fd, operation)这个函数。

其中,参数 fd 表示文件描述符;参数 operation 指定要进行的锁操作,该参数的取值有如下几种:

  • LOCK_SH:表示要创建一个共享锁,在任意时间内,一个文件的共享锁可以被多个进程拥有
  • LOCK_EX:表示创建一个排他锁,在任意时间内,一个文件的排他锁只能被一个进程拥有
  • LOCK_UN:表示删除该进程创建的锁
  • LOCK_MAND:它主要是用于共享模式强制锁,它可以与 LOCK_READ 或者 LOCK_WRITE联合起来使用,从而表示是否允许并发的读操作或者并发的写操作
import fcntl
import threading
import time
def writetoTxt(txtFile):
    id = threading.currentThread().getName()
    with open(txtFile, 'a') as f:
        fcntl.flock(f.fileno(), fcntl.LOCK_EX) #加锁
        print "{0} acquire lock".format(id)
        f.write("write from {0} \r\n".format(id))
        time.sleep(3)
    # 在with块外,文件关闭,自动解锁
    print "{0} exit".format(id)
for i in range(5):
    myThread = threading.Thread(target=writetoTxt, args=("test.txt",))
    myThread.start()

代码运行期间,控制台将依次打印哪个线程获得了锁,在对文件进行读写。

Thread-1 acquire lock
Thread-1 exit
Thread-2 acquire lock
Thread-2 exit
Thread-3 acquire lock
Thread-3 exit
Thread-5 acquire lock
Thread-5 exit
Thread-4 acquire lock
Thread-4 exit
fcntl.flock(f.fileno(), fcntl.LOCK_EX)

对文件加锁,如果有其他线程尝试对test文件加锁,会被阻塞。

当线程执行完毕的时候,锁会自动释放。或者也可以采取主动的方式解锁:调用

fcntl.flock(f.fileno(),fcntl.LOCK_UN)

函数, 对文件test解锁

使用线程锁

当多个线程共享一个数据的时候,必须要进行同步的控制,不然会出现不可预期的结果,即 “线程不安全”

线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁。
互斥锁为资源引入一个状态:锁定/非锁定。
某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;
直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。
互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。

threading模块中定义了Lock类,可以方便的处理锁定:

mutex = threading.Lock() mutex.acquire([timeout]) mutex.release()

使用互斥锁实现上面的例子的代码如下:

import threading
import time
def writetoTxt(txtFile):
    id = threading.currentThread().getName()
    mutex.acquire(10)
    with open(txtFile, 'a') as f:
        print "Thread {0} acquire lock".format(id)
        f.write("write from thread {0} \r\n".format(id))
        time.sleep(3)
    mutex.release()
    print "Thread {0} exit".format(id)
mutex = threading.Lock()
for i in range(5):
    myThread = threading.Thread(target=writetoTxt, args=("test.txt",))
    myThread.start()

(上述代码本质上是一个顺序执行的单线程)

Thread Thread-1 acquire lock
Thread Thread-1 exit
Thread Thread-2 acquire lock
Thread Thread-2 exit
Thread Thread-3 acquire lock
Thread Thread-3 exit
Thread Thread-4 acquire lock
Thread Thread-4 exit
Thread Thread-5 acquire lock
Thread Thread-5 exit

当一个线程调用锁的acquire()方法获得锁时,锁就进入“locked”状态。每次只有一个线程可以获得锁。如果此时另一个线程试图获得这个锁,该线程就会变为“blocked”状态,称为“同步阻塞”。
直到拥有锁的线程调用锁的release()方法释放锁之后,锁进入“unlocked”状态。线程调度程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入运行(running)状态。

其中,使用Condition对象的wait()、notify_all()方法来实现读操作的等待和唤醒,使用Lock对象来实现写操作的互斥。本文介绍了Python中实现读写锁的方法,并提供了相应的源代码。读写锁适用于读操作远多于写操作的场景,可以提高并发处理的效率。在并发编程中,读写锁是常用的一种同步机制。在本文中,我们将使用Python语言实现一个简单的读写锁,并提供相应的源代码。读写锁(ReadWrite Lock)是一种同步机制,它允许多个线程同时读取共享资源,但只允许一个线程进行写操作。 本文实例为大家分享了python多线程同步之文件读写控制的具体代码,供大家参考,具体内容如下 1、实现文件读写文件ltz_schedule_times.py #! /usr/bin/env python #coding=utf-8 import os def ReadTimes(): res = [] if os.path.exists('schedule_times.txt'): fp = open('schedule_times.txt', 'r') else: os.system('touch schedule_times.txt') fp = o  前几天突然有人问我要伤感的诗歌,我在网上搜了一下,感觉古人很强,情感表达的相当纯洁,真切。          夜雨寄北                          君问归期未有期,巴山夜雨涨秋池。何当共剪西窗烛,却话巴山夜雨时。                       无题相间时难别亦难,东风无力百花残。春蚕到死丝方尽,蜡炬成灰泪始干。晓镜但愁云鬓改,夜吟应觉月光寒。蓬山此去无多路,青 作为一个python菜鸟,最近在利用python写个多线程项目的时候,遇见了线程之间的数据调用的问题。遂提供一个简单的调用dome与大家分享一下,若有更好的数据调用方式欢迎留言。 本文涉及的知识点是:python多线程/python项目文件之间的类的引用/python多线程之间的变量调用 本人不喜欢一上来就定义一大堆全局变量,因此经常通过调用类属性的方法来实现多个文本之间变量共享。这么做的问题就在于,项目复杂度提升以后,我就再也找不见某些变量了,俗称埋藏了无数只bug。 痛定思痛后,决定在类的内. threading模块线程简述线程(轻量级进程)与进程类似,不过它们是在同一个进程下执行的,并共享相同的上下文。可以将它们认为是在一个主进程或"主线程"中并行运行的一些"迷你进程"。线程包括开始、执行顺序和结束三部分。它有一个指令指针,用于记录运行的上下文。它其他线程运行时,它可以被抢占(中断)和临时挂起(睡眠/加锁)---这种做法叫做让步(yielding)。多线程的创建使用Thread类,可以... python多线程返回值问题重写Thread类的run方法:可以重新写join方法,并且在run方法中给对象设置了一个属性,_return这个属性的值就是线程的执行结果,最后在join方法中return出来。 在现实生活中,如果一个人团队正在共同完成任务,那么他们之间应该有通信,以便正确完成任务。同样的比喻也适用于线程。在编程中,要减少处理器的理想时间,我们创建了多个线程,并为每个线程分配不同的子任务。因此,必须有一个通信设施,他们应该互相沟通交流,以同步的方式完成工作。考虑以下与线程通信相关的重要问题 - 我们都知道,代码编程不是固定的东西,而是非常灵活的内容,根据不同的内容,我们可以拓展出很多条内容,最终目的还是为了可以实现结果,给大家举例说明其中一个最常用的多线程吧~以及实现的几种方式。1. 用函数创建多线程Python3中,Python提供了一个内置模块 threading.Thread,可以很方便地让我们创建多线程。举个例子importtimefromthreadingimport...
 
推荐文章