相关疑难解决方法(0)

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

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

unix file-io posix atomic atomicity

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

`write(2)`对本地文件系统的原子性

显然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)

c file-io posix multiprocessing

17
推荐指数
4
解决办法
5175
查看次数

fwrite和write之间的主要区别是什么?

我正在编写一个回调函数C:

static size_t writedata(void *ptr, size_t size, size_t nmemb, void *stream){

        size_t written = fwrite(ptr, size, nmemb, (FILE)*stream);
        return written;
}
Run Code Online (Sandbox Code Playgroud)

此函数将用于另一个函数,该函数执行HTTP请求,检索请求并将其写入本地计算机.该writedata功能将用于后面的部分.整个操作必须是multithreaded,所以我write和之间存在疑问fwrite.可能有人帮助我,概述之间的差异write(),并fwrite()C,所以我可以选择哪一个最适合到我的问题吗?

c c++

11
推荐指数
2
解决办法
2万
查看次数

如果我从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
查看次数

在 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
查看次数