相关疑难解决方法(0)

文件是否在UNIX中附加原子?

一般来说,当我们从多个进程附加到UNIX中的文件时,我们可以理所当然地认为什么?是否有可能丢失数据(一个进程会覆盖其他进程)?数据是否可能被破坏?(例如,每个进程在每个追加到日志文件时附加一行,是否有可能两行被破坏?)如果追加在上述意义上不是原子的,那么确保互斥的最佳方法是什么?

unix file-io posix atomic atomicity

99
推荐指数
4
解决办法
3万
查看次数

了解来自多个进程的并发文件写入

从这里:文件是否在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)

c unix file-io operating-system mpi

14
推荐指数
3
解决办法
1万
查看次数

fwrite原子?

一个简单的问题:

我需要在我的程序中添加一些日志记录.

如果两个进程在同一个文件上使用"fwrite"但文件描述符不同,那么写入的日志消息将是原子的或混合的.有长度限制吗?

是否定义了ANSI-C行为或实现定义?如果后来MacOSX,Linux和Windows MSVC上有什么?

c file-io atomic

12
推荐指数
2
解决办法
7699
查看次数

如何从两个进程同步 - 在一个文件上进行原子写入?

我有两个进程,每个进程写大数据缓冲区,我想控制同步这些进程的写入到一个文件.

处理1写入缓冲器A包括(A1,A2,A3)和处理2写入缓冲器B,包括(B1,B2,B3).当我们使用write()系统调用将这些缓冲区写入磁盘到同一个文件(整个缓冲区一次:)时write(fd, A, sizeof(A)),文件架构如何?

  • 它是这样的:A,B或B,A可能吗?
  • 或者它可能是这样的:A1,A2,B1,A3,......

我问这个是因为系统调用是原子的.如果我们写的数据缓冲区太大会发生什么.它是否像常规磁盘文件的管道?

c atomic

6
推荐指数
1
解决办法
1202
查看次数

如果我从python中的多个不同进程登录到同一文件,该怎么办?

我花了几个小时来研究行为,首先是关于这些问题:

看来,如果在打开文件时使用'O_APPEND'标志,则在Linux上从多个进程登录到同一文件总是可以的。而且我相信python肯定会在其日志记录模块中使用'O_APPEND'标志。

并通过一个小测试:

#!/bin/env python
import os
import logging

logger = logging.getLogger('spam_application')
logger.setLevel(logging.DEBUG)
# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
logger.addHandler(fh)
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)

for i in xrange(10000):
    p = os.getpid()
    logger.debug('Log line number %s in %s', i, p)
Run Code Online (Sandbox Code Playgroud)

我用它运行:

./test.py & ./test.py & ./test.py & ./test.py &
Run Code Online (Sandbox Code Playgroud)

我发现spam.log中没有错。此行为可能支持上述结论。

但是问题来了:

  • 这是什么意思在这里
  • 什么是使用场景,只为文件旋转?

最后,如果两个进程正在同一文件上执行写操作,那是指它们正在调用同一文件上的write(2),谁可以确保来自两个进程的数据不会交织(内核或文件系统?),以及如何交织。[注意:我只想深入了解写系统调用,对此的任何欢迎。

编辑1:

难道这 …

python logging atomic multiprocessing atomicity

6
推荐指数
2
解决办法
2343
查看次数

两个进程写入一个文件,防止混合输出

我想从两个进程中获取输出并将它们合并到一个文件中,例如:

proc1 >> output &
proc2 >> output &
Run Code Online (Sandbox Code Playgroud)

问题是输出可能会在最终文件中混淆。例如,如果第一个进程写入:

你好

第二个过程写道:

再见

结果可能类似于:

海贝罗

但我希望它们在单独的行中(顺序不重要):

再见

你好

所以我使用 flock 通过以下脚本同步写入文件:

exec 200>>output
while read line;
  flock -w 2 200
  do echo $line>>output
  flock -u 200
done
Run Code Online (Sandbox Code Playgroud)

并运行如下进程:

proc1 | script &
proc2 | script &
Run Code Online (Sandbox Code Playgroud)

现在的问题是性能显着下降。如果没有同步,每个进程可以以 4MB/秒的速度写入,但使用同步脚本的写入速度为 1MB/秒。

谁能帮助我如何合并两个进程的输出并防止混合输出?

编辑:我意识到行长度和 std 缓冲区大小之间存在关系,如果每行的大小小于 std 缓冲区大小,那么一切都很好,没有任何混合(至少在我的测试中)。所以我用 bufsize 命令运行了每个脚本:

bufsize -o10KB proc1 | script &
bufsize -o10KB proc2 | script &
Run Code Online (Sandbox Code Playgroud)

现在我想确保这个解决方案是防弹的。我找不到缓冲区大小与现在发生的事情之间的任何关系!!!

linux bash redirect synchronization flock

6
推荐指数
1
解决办法
3745
查看次数

unix 中的写操作是原子的吗?

我正在阅读APUE(UNIX 环境中的高级编程),当我看到 $3.11 时遇到了这个问题:

if (lseek(fd, 0L, 2) < 0) /* position to EOF */
err_sys("lseek error");
if (write(fd, buf, 100) != 100) /* and write */
err_sys("write error")
Run Code Online (Sandbox Code Playgroud)

APUE 说:

这适用于单个进程,但如果多个进程使用此技术附加到同一个文件,则会出现问题。.......这里的问题是我们的“定位到文件末尾并写入”的逻辑操作需要两个单独的函数调用(正如我们所展示的)。任何需要多个函数调用的操作都不能是原子的,因为内核总是有可能在两次函数调用之间暂时挂起进程。

它只是说cpu会在lseek和之间的函数调用之间切换write,我想知道它是否也会在一半write操作之间切换?或者更确切地说,是write原子的?如果线程A写"aaaaa",线程B写"bbbbb",结果会是"aabbbbbaaa"

更重要的是,在APUE说pread并且pwrite都是原子操作之后,这是否意味着这些函数使用mutexlock内部是原子的?

c unix posix atomic

6
推荐指数
1
解决办法
3393
查看次数

Python的file.write是原子的吗?

file.write原子操作在Python或C?

考虑以下两个线程

线程1

with open('foo', 'a') as f:
    f.write('123456')
Run Code Online (Sandbox Code Playgroud)

线程2

with open('foo', 'a') as f:
    f.write('abcdef')
Run Code Online (Sandbox Code Playgroud)

我们保证不会像以下一样得到混合文本吗?

1a2b3c4d5e6f
or 
123abc456def
Run Code Online (Sandbox Code Playgroud)

而是得到两个可能的正确结果之一

123456abcdef
abcdef123456
Run Code Online (Sandbox Code Playgroud)

请注意,在每个线程中都有一次写入调用,显然原子多次写入需要某种锁定.我也知道基于文件的锁.这个问题的理想答案是肯定/不带证据/文件.

python concurrency multithreading locking

5
推荐指数
1
解决办法
507
查看次数

在 ext4 上覆盖小文件是原子的吗?

假设我们有一个FILE_SIZE字节文件,并且:

  • FILE_SIZE <= min(page_size, physical_block_size);
  • 文件大小永远不会改变(即永远不会执行truncate()或追加write());
  • 文件只能通过使用以下方法完全覆盖其内容来修改:

    pwrite(fd, buf, FILE_SIZE, 0);
    

是否保证ext4

  1. 这种写入对于并发读取来说是原子的吗?
  2. 对于系统崩溃,此类写入是事务性的吗?

    (即,崩溃后文件的内容完全来自先前的写入,我们永远不会看到部分写入或空文件)

第二个是真的吗:

  • data=ordered
  • data=journal或者用单个文件日志启用?

    (使用ioctl(fd, EXT4_IOC_SETFLAGS, EXT4_JOURNAL_DATA_FL)

  • 什么时候physical_block_size < FILE_SIZE <= page_size


我发现了相关问题,该问题链接了 2011 年的讨论。但是:

  • 我没有找到我的问题的明确答案2
  • 我想知道,如果上述情况属实,是否在某处有记录

linux filesystems linux-kernel ext4

5
推荐指数
1
解决办法
1398
查看次数

在 bash 脚本中并行运行数组中的每个元素

假设我有一个如下所示的 bash 脚本:

array=( 1 2 3 4 5 6 )

for each in "${array[@]}"
do
  echo "$each"

  command --arg1 $each

done
Run Code Online (Sandbox Code Playgroud)

如果我想并行运行循环中的所有内容,我可以更改command --arg1 $eachcommand --arg1 $each &.

但现在假设我想获取结果command --arg1 $each并用这些结果做一些事情,如下所示:

array=( 1 2 3 4 5 6 )
for each in "${array[@]}"
do
  echo "$each"

  lags=($(command --arg1 $each)

  lngth_lags=${#lags[*]}

  for (( i=1; i<=$(( $lngth_lags -1 )); i++))
  do

    result=${lags[$i]}
    echo -e "$timestamp\t$result" >> $log_file
    echo "result piped"

  done

done
Run Code Online (Sandbox Code Playgroud)

如果我只是&在 的末尾添加 …

bash shell

5
推荐指数
1
解决办法
5956
查看次数