我正在研究一个可以通过网络访问的python脚本,因此会有多个用户试图同时附加到同一个文件.我担心这可能导致竞争条件,如果多个用户同时写入同一文件,它可能会损坏文件.
例如:
#!/usr/bin/env python
g = open("/somepath/somefile.txt", "a")
new_entry = "foobar"
g.write(new_entry)
g.close
Run Code Online (Sandbox Code Playgroud)
我是否必须使用锁定文件,因为此操作看起来很危险.
python concurrency simultaneous text-files simultaneous-calls
有人告诉我,日志记录不能用于多处理.在多处理混淆日志的情况下,您必须执行并发控制.
但我做了一些测试,似乎在使用多处理登录时没有问题
import time
import logging
from multiprocessing import Process, current_process, pool
# setup log
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='/tmp/test.log',
filemode='w')
def func(the_time, logger):
proc = current_process()
while True:
if time.time() >= the_time:
logger.info('proc name %s id %s' % (proc.name, proc.pid))
return
if __name__ == '__main__':
the_time = time.time() + 5
for x in xrange(1, 10):
proc = Process(target=func, name=x, args=(the_time, logger))
proc.start()
Run Code Online (Sandbox Code Playgroud)
正如您从代码中看到的那样.
我故意让子进程在同一时刻(开始后5s)写日志以增加冲突的可能性.但是根本没有冲突.
所以我的问题是我们可以在多处理中使用日志记录吗?为什么这么多帖子说我们不能?
显然POSIX说明了这一点
文件描述符或流在其引用的打开文件描述上称为"句柄"; 打开的文件描述可能有几个句柄.[...]应用程序影响第一个句柄上文件偏移量的所有活动都应暂停,直到它再次成为活动文件句柄.[...]句柄不需要在同一过程中应用这些规则.- POSIX.1-2008
和
如果两个线程分别调用[write()函数],则每个调用应该看到另一个调用的所有指定效果,或者没有看到它们.- POSIX.1-2008
我对此的理解是,当第一个进程发出
write(handle, data1, size1)第二个进程并且第二个进程发出时
write(handle, data2, size2),写入可以以任何顺序发生,但是data1并且data2 必须既是原始的又是连续的.
但运行以下代码会给我带来意想不到的结果.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
die(char *s)
{
perror(s);
abort();
}
main()
{
unsigned char buffer[3];
char *filename = "/tmp/atomic-write.log";
int fd, i, j;
pid_t pid;
unlink(filename);
/* XXX Adding O_APPEND to the flags cures it. Why? */
fd = open(filename, O_CREAT|O_WRONLY/*|O_APPEND*/, 0644);
if (fd < 0)
die("open failed"); …Run Code Online (Sandbox Code Playgroud) 从这里:文件是否在UNIX中附加原子
考虑多个进程打开同一文件并附加到其中的情况.O_APPEND保证寻找到文件的末尾然后开始写操作是原子的.因此,只要每个写入大小<= PIPE_BUF,多个进程就可以附加到同一个文件中,并且任何进程都不会覆盖任何其他进程的写入.
我编写了一个测试程序,其中多个进程打开并写入同一个文件(write(2)).我确保每个写入大小> PIPE_BUF(4k).我期待看到进程覆盖其他人数据的实例.但那并没有发生.我测试了不同的写入大小.那只是运气还是有理由不这样做?我的最终目标是了解附加到同一文件的多个进程是否需要协调其写入.
这是完整的计划.每个进程都创建一个int缓冲区,用它填充所有值rank,打开一个文件并写入它.
规格:Opensuse 11.3 64位的OpenMPI 1.4.3
编译为:mpicc -O3 test.c,运行方式:mpirun -np 8 ./a.out
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int
main(int argc, char** argv) {
int rank, size, i, bufsize = 134217728, fd, status = 0, bytes_written, tmp_bytes_written;
int* buf;
char* filename = "/tmp/testfile.out";
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
buf = (int*) malloc (bufsize * sizeof(int));
if(buf == NULL) {
status = -1; …Run Code Online (Sandbox Code Playgroud) 在大型php应用程序中写入文件的最佳方法是什么.可以说每秒需要大量的写入.怎样才能解决这个问题.
我可以打开文件并附加数据.或者我应该打开,锁定,写入和解锁.
将处理该文件将会发生什么,并且需要编写其他数据.这项活动会丢失,还是会被保存.如果这将被保存将停止应用程序.
如果你去过,谢谢你的阅读!
我已经看到了很多关于写入文件的问题,但我想知道打开文本文件最有效的方法是什么,附加一些数据然后在你要从多个连接写入时再次关闭它(即并行计算情况),并不能保证每个连接何时都要写入文件.
例如,在下面的玩具示例中,它只使用我桌面上的核心,它似乎工作正常,但我想知道如果写入时间越长并且写入文件的进程数量增加,此方法是否容易失败(特别是在可能存在延迟的网络共享中).
任何人都可以建议一种强大的,明确的方式,当可能有其他想要同时写入文件的从属进程时,应该打开,写入然后关闭连接吗?
require(doParallel)
require(doRNG)
ncores <- 7
cl <- makeCluster( ncores , outfile = "" )
registerDoParallel( cl )
res <- foreach( j = 1:100 , .verbose = TRUE , .inorder= FALSE ) %dorng%{
d <- matrix( rnorm( 1e3 , j ) , nrow = 1 )
conn <- file( "~/output.txt" , open = "a" )
write.table( d , conn , append = TRUE , col.names = FALSE )
close( conn )
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找最好的 …
我在一些消息来源中读到,print命令不是线程安全的,而且解决方法是使用sys.stdout.write命令,但它仍然不适用于我,并且写入STDOUT不是原子的.
这是一个简短的例子(称为此文件parallelExperiment.py):
import os
import sys
from multiprocessing import Pool
def output(msg):
msg = '%s%s' % (msg, os.linesep)
sys.stdout.write(msg)
def func(input):
output(u'pid:%d got input \"%s\"' % (os.getpid(), str(input)))
def executeFunctionInParallel(funcName, inputsList, maxParallelism):
output(u'Executing function %s on input of size %d with maximum parallelism of %d' % (
funcName.__name__, len(inputsList), maxParallelism))
parallelismPool = Pool(processes=maxParallelism)
executeBooleanResultsList = parallelismPool.map(funcName, inputsList)
parallelismPool.close()
output(u'Function %s executed on input of size %d with maximum parallelism of %d' % (
funcName.__name__, …Run Code Online (Sandbox Code Playgroud) 我正在尝试根据Lehman 和 Yao 在本文中建议的数据结构(B链接树)和算法来实现数据库索引。在第 2 页,作者指出:
磁盘分区为固定大小的部分(物理页;在本文中,这些对应于树的节点)。这些是进程可以读取或写入的唯一单元。[强调我的](...)
(...) 允许进程锁定和解锁磁盘页面。这个锁赋予该进程对该页面的独占修改权;此外,进程必须锁定页面才能修改该页面。(...)锁 不会阻止其他进程读取锁定的页面。[强调我的]
我不完全确定我的解释是正确的(我不习惯阅读学术论文),但我认为可以从强调的句子中得出结论,作者的意思是读取和写入页面的操作被假定为“原子” ,从某种意义上说,如果进程 A 已经开始读取(相应地写入)页面,则另一个进程 B 可能不会开始写入(相应地读取)同一页面,直到 A 完成其读取(相应地写入)操作. 多个进程同时读取同一个页面当然是一个合法的条件,因为多个进程同时在不同的页面上执行任意操作(页面 P 上的进程 A,页面 Q 上的进程 B,页面 R 上的进程 C,等等。 )。
我的解释正确吗?
我可以假设 POSIX'read()和write()系统调用在上述意义上是“原子的”吗?我是否可以依靠这些具有一些内部逻辑的系统调用来根据文件描述符的位置和要读取或写入的块的指定大小来确定是否应该暂时阻止特定read()或write()调用?
如果上述问题的答案是“否”,我应该如何推出自己的锁定机制?
我必须从我的Java应用程序中读取一个文本文件.
该文件包含许多行,此文件每隔X分钟从外部未知应用程序更新,该应用程序将新行附加到文件.
我必须从文件中读取所有行,然后我必须删除我刚读过的所有记录.
是否有可能让我逐行读取文件,删除我读取的每一行,同时允许外部应用程序将其他行追加到文件中?
此文件位于Samba共享文件夹中,因此我使用jCIFS来读取/写入文件和BufferedReader Java类.
提前致谢
如果我在运行此代码的一台机器上有 4 个、8 个或更多线程和集群,是否会出现日志文件/文件编写器的资源争用?如果是这样,您能发布一个示例来说明吗?到目前为止,我所做的所有测试似乎都表明写入数据不会交织在一起,也不会被丢弃,但我并不是 100% 相信
谢谢!
var errLog = fs.createWriteStream(... + '/error.log');
GLOBAL.dbLog = fs.createWriteStream(... + '/db.log');
Run Code Online (Sandbox Code Playgroud)