- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
在阅读 APUE(第 3 版)一书时,我遇到了 open 系统调用及其让用户打开文件进行 write
原子操作的能力,具有 O_APPEND
模式含义也就是说,多个进程可以写入文件描述符,内核确保多个进程写入单个文件的数据不会重叠,并且所有行都完好无损。
在使用 C/C++ 程序对开放式系统调用进行成功实验后,我能够对其进行验证,并且它的工作原理与书中描述的一样。我能够启动写入单个文件的多个进程,并且所有行都可以考虑到它们的进程 PID。
我希望通过 perl sysopen
观察到相同的行为,因为我有一些工作可以从这种行为中获益。尝试了一下,但实际上没有用。当我分析输出文件时,我能够看到竞争条件的迹象(可能),因为有很多次交错的行。
问题:perl sysopen
调用和linux的open系统调用不一样吗?是否可以实现这种多进程对单个文件的原子写操作?
编辑:添加 C 代码和用于测试的 perl 代码。
C/C++代码
int main(void)
{
if ((fd = open("outfile.txt",O_WRONLY|O_CREAT|O_APPEND)) == -1) {
printf ("failed to create outfile! exiting!\n");
return -1;
}
for (int counter{1};counter<=MAXLINES;counter++)
{ /* write string 'line' for MAXLINES no. of times */
std::string line = std::to_string(ACE_OS::getpid())
+ " This is a sample data line ";
line += std::to_string(counter) + " \n";
if ((n = write(fd,line.c_str(),strlen(line.c_str()))) == -1) {
printf("Failed to write to outfile!\n";
}
}
return 0;
}
Perl 代码
#!/usr/bin/perl
use Fcntl;
use strict;
use warnings;
my $maxlines = 100000;
sysopen (FH, "testfile", O_CREAT|O_WRONLY|O_APPEND) or die "failed sysopen\n";
while ($maxlines != 0) {
print FH "($$) This is sample data line no. $maxlines\n";
$maxlines--;
}
close (FH);
__END__
更新(初步故障排除后):
感谢以下答案中提供的信息,我能够让它正常工作。虽然我遇到了一些缺失行的问题,这是由于我使用 O_TRUNC
打开每个进程的文件,我不应该这样做,但最初错过了它。经过仔分割析 - 我发现了问题并进行了更正。一如既往 - Linux 永远不会让你失望:)。
这是我用来启动进程的 bash 脚本:
#!/bin/bash
# basically we spawn "$1" instances of the same
# executable which should append to the same output file.
max=$1
[[ -z $max ]] && max=6
echo "creating $max processes for appending into same file"
# this is our output file collecting all
# the lines from all the processes.
# we truncate it before we start
>testfile
for i in $(seq 1 $max)
do
echo $i && ./perl_read_write_with_syscalls.pl 2>>_err &
done
# end.
从输出文件验证:
[compuser@lenovoe470:07-multiple-processes-append-to-a-single-file]$ ls -lrth testfile
-rw-rw-r--. 1 compuser compuser 252M Jan 31 22:52 testfile
[compuser@lenovoe470:07-multiple-processes-append-to-a-single-file]$ wc -l testfile
6000000 testfile
[compuser@lenovoe470:07-multiple-processes-append-to-a-single-file]$ cat testfile |cut -f1 -d" "|sort|uniq -c
1000000 (PID: 21118)
1000000 (PID: 21123)
1000000 (PID: 21124)
1000000 (PID: 21125)
1000000 (PID: 21126)
1000000 (PID: 21127)
[compuser@lenovoe470:07-multiple-processes-append-to-a-single-file]$
观察:
令我惊讶的是,系统上根本没有等待平均负载。我没想到。我相信内核一定已经以某种方式解决了这个问题,但不知道它是如何工作的。我有兴趣了解更多。
这可能有哪些应用?
我做了很多文件到文件的协调工作,我们(在工作中)总是需要解析巨大的数据文件(例如每个 30gb - 50gb)。有了这个工作 - 我现在可以进行并行操作,而不是我以前的方法,包括:散列文件 1,然后散列文件 2,然后比较来自 2 个文件的键值对。现在我可以并行执行散列部分并进一步缩短所需时间。
谢谢
最佳答案
open
或 sysopen
都没有关系;关键是使用 syswrite
和 sysread
而不是 print
/printf
/say
/etc 和 readline
/read
/eof
/etc.
syswrite
映射到单个 write(2)
调用,而 print
/printf
/ say
/etc 会导致多次调用 write(2)
(即使启用了自动刷新)。[1]
sysread
映射到单个 read(2)
调用,而 readline
/read
/ eof
/etc 会导致多次调用 read(2)
。
因此,通过使用 syswrite
和 sysread
,如果您在POSIX系统。
print
/printf
/say
/etc,并且将您的写入限制为小于(显式)之间的缓冲区大小或自动)刷新,您将收到一个 write(2)
调用。缓冲区大小在旧版本的 Perl 中为 4 KiB,在新版本的 Perl 中默认为 8 KiB。 (大小在构建 perl
时决定。)关于linux - perl sysopen 可以打开文件进行原子写入吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54463525/
我喜欢 smartcase,也喜欢 * 和 # 搜索命令。但我更希望 * 和 # 搜索命令区分大小写,而/和 ?搜索命令遵循 smartcase 启发式。 是否有隐藏在某个地方我还没有找到的设置?我宁
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 10年前关闭。 Improve this qu
从以下网站,我找到了执行java AD身份验证的代码。 http://java2db.com/jndi-ldap-programming/solution-to-sslhandshakeexcepti
似乎 melt 会使用 id 列和堆叠的测量变量 reshape 您的数据框,然后通过转换让您执行聚合。 ddply,从 plyr 包看起来非常相似..你给它一个数据框,几个用于分组的列变量和一个聚合
我的问题是关于 memcached。 Facebook 使用 memcached 作为其结构化数据的缓存,以减少用户的延迟。他们在 Linux 上使用 UDP 优化了 memcached 的性能。 h
在 Camel route ,我正在使用 exec 组件通过 grep 进行 curl ,但使用 ${HOSTNAME} 的 grep 无法正常工作,下面是我的 Camel 路线。请在这方面寻求帮助。
我正在尝试执行相当复杂的查询,在其中我可以排除与特定条件集匹配的项目。这是一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我正在尝试执行相当复杂的查询,我可以在其中排除符合特定条件集的项目。这里有一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我发现了很多嵌入/内容项目的旧方法,并且我遵循了在这里找到的最新方法(我假设):https://blog.angular-university.io/angular-ng-content/ 我正在尝试
我正在寻找如何使用 fastify-nextjs 启动 fastify-cli 的建议 我曾尝试将代码简单地添加到建议的位置,但它不起作用。 'use strict' const path = req
我正在尝试将振幅 js 与 React 和 Gatsby 集成。做 gatsby developer 时一切看起来都不错,因为它发生在浏览器中,但是当我尝试 gatsby build 时,我收到以下错
我试图避免过度执行空值检查,但同时我想在需要使代码健壮的时候进行空值检查。但有时我觉得它开始变得如此防御,因为我没有实现 API。然后我避免了一些空检查,但是当我开始单元测试时,它开始总是等待运行时异
尝试进行包含一些 NOT 的 Kibana 搜索,但获得包含 NOT 的结果,因此猜测我的语法不正确: "chocolate" AND "milk" AND NOT "cow" AND NOT "tr
我正在使用开源代码共享包在 iOS 中进行 facebook 集成,但收到错误“FT_Load_Glyph failed: glyph 65535: error 6”。我在另一台 mac 机器上尝试了
我正在尝试估计一个标准的 tobit 模型,该模型被审查为零。 变量是 因变量 : 幸福 自变量 : 城市(芝加哥,纽约), 性别(男,女), 就业(0=失业,1=就业), 工作类型(失业,蓝色,白色
我有一个像这样的项目布局 样本/ 一种/ 源/ 主要的/ java / java 资源/ .jpg 乙/ 源/ 主要的/ java / B.java 资源/ B.jpg 构建.gradle 设置.gr
如何循环遍历数组中的多个属性以及如何使用map函数将数组中的多个属性显示到网页 import React, { Component } from 'react'; import './App.css'
我有一个 JavaScript 函数,它进行 AJAX 调用以返回一些数据,该调用是在选择列表更改事件上触发的。 我尝试了多种方法来在等待时显示加载程序,因为它当前暂停了选择列表,从客户的 Angul
可能以前问过,但找不到。 我正在用以下形式写很多语句: if (bar.getFoo() != null) { this.foo = bar.getFoo(); } 我想到了三元运算符,但我认
我有一个表单,在将其发送到 PHP 之前我正在执行一些验证 JavaScript,验证后的 JavaScript 函数会发布用户在 中输入的文本。页面底部的标签;然而,此消息显示短暂,然后消失...
我是一名优秀的程序员,十分优秀!