背景

碰到一个偶现的编译出错问题,如图

报错的信息是

cp: 无法创建普通文件"xxx": 文件已存在

排查原因

看了下 Makefile,这句非常简单,就是 cp ./xxx ../xxx 而已,本身没什么问题。

那再结合上下文出现的打印,一个异常之处就是 Makfeile 被并行重复执行了,猜测是并行导致 cp 操作出错。

只考虑解决问题,那无疑是修改外层 Makefile ,避免此处被并行重复执行,至少这句 cp 不要被并行,就可以解决了。

但为什么 cp 并行执行会出错呢?如果在另外的场景下确实有并行执行cp的可能,有没有办法规避这个错误呢?这就得探究下了。

单独执行 cp,默认的行为就是覆盖已存在的文件,并不会因为 “文件已存在” 这样的原因出错,随便做下实验,touch a b; cp a b就可以确认正常是不会报错的。

那问题还是得结合并行来分析,碰到这种情况,要么是从搜索资料获得提示,要么就是实践出真知,自己设计一个可快速复现的方式,然后使用调试工具来追踪问题发生时的具体情况。

具体到这个问题,我是搜索到相同的stackexchange问题,那就省点工夫不用自己去复现分析了。

这里插下题外话,搜索优先使用google,对于中文报错信息查不到的可改成英文查询。例如中文的 cp: 无法创建普通文件 文件已存在 就不好找到答案,换成 cp cannot create regular file file exists 就好找了。(只敲一部分,搜索引擎就能提示完整的信息)

stackexchage上给出了一个脚本,用于复现问题并使用 strace 将追踪的系统调用记录下来

#!/bin/bash

touch a

f() {
while true; do
rm -f b
strace -o /tmp/cp${BASHPID}.trace cp a b || break
done
} cleanup() {
kill -9 %1 %2
} f &
f & trap cleanup exit wait

附上我自己的实验结果,可以看出cp的实现上,会先用stat来判断目标文件b是否存在,如果不存在则会使用 open("b", O_WRONLY|O_CREAT|O_EXCL, 0664) 来创建目标文件并将源文件写入目标文件,完成复制。

那么如果两个 cp 并发,就可能出现

cp1                  cp2
stat判断b不存在
stat判断b不存在
open成功,创建文件b
open失败,因为此时文件已经被cp1创建好了

stracelog 看到的就是

由于 cp 不是原子的,如果两个 cp 刚好几乎同时执行,则可能两个 cpstat都判断到文件不存在,那最终只有一个 cp 能创建文件,另一个就失败了。

顺便看看,文件存在和不存在的open参数差异

解决办法

既然两个cp同时执行会出错,那就加锁呗。

如果所有调用 cp 的地方都是我们可控的,那劝告锁就足够了,在 shell 中可以直接使用 flock

约定好一个文件锁x, 将原来的cp a b 改成 flock x cp a b 即可。

例如正常在两个控制台中,执行top是可以并行的,但如果改成执行 flock /tmp/toplock top,那就只有控制台1会执行top,控制台2则处于等待文件锁的状态。此时若控制台1退出top,则控制台2获得锁,开始执行top

更多文件锁的细节,可以看看 man flock

blog: https://www.cnblogs.com/zqb-all/p/12942556.html

公众号:https://sourl.cn/S42YSr

cp: 无法创建普通文件 : 文件已存在的更多相关文章

  1. [转]iOS学习笔记(2)--Xcode6.1创建仅xib文件无storyboard的hello world应用

    转载地址:http://www.mamicode.com/info-detail-514151.html 由于Xcode6之后,默认创建storyboard而非xib文件,而作为初学,了解xib的加载 ...

  2. iOS学习笔记(2)--Xcode6.1创建仅xib文件无storyboard的hello world应用

    http://www.mamicode.com/info-detail-514151.html 由于Xcode6之后,默认创建storyboard而非xib文件,而作为初学,了解xib的加载原理很重要 ...

  3. JAVA之旅(二十八)——File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤

    JAVA之旅(二十八)--File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤 我们可以继续了,今天说下File 一.File概述 文件的操作是非常 ...

  4. Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件

    写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...

  5. [Swift]在Swift项目中创建桥接头文件,Swift文件和Objective-C文件相互调用

    创建一个Swift项目[demo],以下内容Swift文件和Objective-C文件相互调用都是在Swift项目中. 一.Swift文件调用Objective-C文件 新建文件夹[SupportFi ...

  6. 【练习】Java中的读文件,文件的创建,写文件

    前言 大家好,给大家带来Java中的读文件,文件的创建,写文件的概述,希望你们喜欢 读文件 public static void read(String path,String filename){ ...

  7. Excel催化剂开源第4波-ClickOnce部署要点之导入数字证书及创建EXCEL信任文件夹

    Excel催化刘插件使用Clickonce的部署方式发布插件,以满足用户使用插件过程中,需要对插件进行功能升级时,可以无痛地自动更新推送新版本.但Clickonce部署,对用户环境有较大的要求,前期首 ...

  8. Java中的读文件,文件的创建,写文件

    前言 大家好,我是 Vic,今天给大家带来Java中的读文件,文件的创建,写文件的概述,希望你们喜欢 示意图 读文件 public static void read(String path,Strin ...

  9. 为什么vue-cli创建的build文件下没有dev-server.js文件

    在新版本的Vue开发中,通过vue-cli创建的build文件夹下面已经没有了旧版本中的dev-server.js文件新版本的vue已将dev-server.js与webpack.dev.conf.j ...

随机推荐

  1. iOS开发之结合asp.net webservice实现文件上传下载

    iOS开发中会经常用到文件上传下载的功能,这篇文件将介绍一下使用asp.net webservice实现文件上传下载. 首先,让我们看下文件下载. 这里我们下载cnblogs上的一个zip文件.使用N ...

  2. THU OS

    前言 最近在学清华的OS课程,实验课做的真厉害. 我们的操作系统课就是写一个系统调用,改下进程软中断通信的代码,代码量不足500...清华是借鉴MIT的课,实验课都是做一个完整的小型操作系统. 一共8 ...

  3. django源码分析——本地runserver分析

    本文环境python3.5.2,django1.10.x系列 1.根据上一篇文章分析了,django-admin startproject与startapp的分析流程后,根据django的官方实例此时 ...

  4. 使用Python实现批量ping操作

    在日常的工作中,我们通常会有去探测目标主机是否存活的应用场景,单个的服务器主机可以通过计算机自带的DOS命令来执行,但是业务的存在往往不是单个存在的,通常都是需要去探测C段的主机(同一个网段下的存活主 ...

  5. Prime Path素数筛与BFS动态规划

    埃拉托斯特尼筛法(sieve of Eratosthenes ) 是古希腊数学家埃拉托斯特尼发明的计算素数的方法.对于求解不大于n的所有素数,我们先找出sqrt(n)内的所有素数p1到pk,其中k = ...

  6. react——key值的理解

    key不是给开发者使用的,是给react在diff算法中使用的,diff算法会比较新旧虚拟dom,并且是同层比较,当同一层中有多个元素的时候,会比较这一层的key值, 如果key相同,属性改变积极更新 ...

  7. 使用Java实现简单的斗地主案例

    使用Java实现简单的斗地主案例 案例说明:使用Java实现简单的斗地主洗牌发牌的操作: 具体规则: 共有54张牌,顺序打乱: 三个玩家参与游戏,三人交替摸牌,每人17张牌,最后留三张为底牌(地主牌) ...

  8. Python爬虫丨大众点评数据爬虫教程(2)

    大众点评数据爬虫获取教程 --- [SVG映射版本] 前言: 大众点评是一款非常受大众喜爱的一个第三方的美食相关的点评网站.从网站内可以推荐吃喝玩乐优惠信息,提供美食餐厅.酒店旅游.电影票.家居装修. ...

  9. qgis控制滚轮转动地图比例尺的变化幅度

    需求:在比例尺1万-10万之间,鼠标滚轮转动比例尺的变化幅度为1万重写滚轮事件 void Xx::wheelEvent(QWheelEvent*event){ double curScale = sc ...

  10. Hexo 博客利用 Nginx 实现中英文切换

    本文记录了对 Hexo 博客进行中英文切换的配置过程,实现同一应用共用模版,任何页面可以切换到另一语言的对应页面,并对未明确语言的访问地址,根据浏览器语言进行自动跳转 实现细则 中英文地址区分 博客中 ...