sqlite3在多进程条件下的问题
sqlite3是一个非常简单的本地数据库,以磁盘文件作为基础。正是因为简单,所以在多进程多线程情况下,需要用户自行决定相应的逻辑。有两种方式来操作数据库:同步、异步。
同步
多进程多线程情况下,如果多个进程或多个线程同时对数据库进行写操作,容易出现一个进程或线程写完数据库之后,另一个持有旧状态的进程或线程又对数据库进行了一次写操作,极易造成数据库损坏。
解决以上问题的方法主要有锁机制,通过对临界区域加锁,来避免多个进程或线程同时对数据库进行操作。
进程锁:python的multiprocess提供了Lock()方法,可以在同一个任务中多个进程之间进行同步。但是,如果涉及到不同任务对同一个文件进行读写,就需要其他的方式来对进程进行同步。这里介绍一种可以用于不同任务之间的文件锁:fcntl。
fcntl有两种不同的加锁方式flock和lockf,flock和fcntl都是系统调用,而lockf是库函数,也是fcntl的封装,因此lockf和fcntl在底层实现是一样的,对文件加锁的效果也是一样的。
几个概念:
文件锁:对整个文件进行加锁
记录锁:对整个文件以及文件的部分字节进行加锁,如fcntl和lockf
排它锁:也可以称为写锁、独占锁,同一时间只有一个进程可以加锁
共享锁:也可以称为读锁,支持多个进行并发的读文件内容,但是不可以写
睡眠锁:如果进程请求的锁被其他进程所持有,则该进行会进行休眠,直到满足条件被唤醒,如semaphore、mutex等。
自旋锁:如果进程请求的锁被其他进程所持有,则该进行不休眠,循环等待,直到满足条件。自旋锁不应被长时间持有。
劝告锁:不要求进程一定遵守规则,可以强制操作,如flock和fcntl
强制锁:是内核行为,在操作系统调用违反约束条件的时候,内核将直接阻拦,如fcntl。
flock
flock(fd, operation)
相关文章