首页 > 解决方案 > 当 C++ 程序正在读取文件而单独的 python GUI 脚本正在写入同一文件时,会发生分段错误

问题描述

我目前正在 Raspbian OS - Debian 上运行它。

我有两个独立的程序同时运行。我有一个 c++ 'engine' 和一个 python 'gui' 接口。我知道可能有更好的做法,但目前他们正在通过平面文件进行通信。本质上,python GUI 使用特定文本写入文件,cmd.sf然后引擎解码完全相同的文件并执行它需要做的任何事情。

设置非常简单:

C++ 引擎:

C++ 程序不断读取cmd.sf文件,如果文件的上下文是-1. 文件更改的那一刻,引擎应该解析 Python GUI 本质上写的内容,并且在成功执行内容告诉引擎执行的任何内容后,它会写回文件-1

Python图形用户界面

在 GUI 端,它是相同的概念,只是它被颠倒了。GUI 还不断地从文件中读取cmd.sf数据,并且不会继续编写相同或不同的指令,直到它知道 C++ 引擎已完成其先前的指令。所以它本质上检查文件以确保它是任何东西但是-1

问题在于,如果我最初设置cmd.sf-1,C++ 引擎通过不断读取和检查文件的内容来成功完成它需要做的事情。但是,在我指示 GUI 更改文件内容的那一刻,C++ 引擎挂起,吐出 seg 错误并中止。

但是,我发现了一些可行的方法,但我终其一生都无法弄清楚原因。如果我要cmd.sf在 geany(我是 Raspbian)等文本编辑器中打开并通过编辑器更改内容并保存,它不会导致段错误。事实上,C++ 引擎注意到文件内容的变化,适当地执行指令并写-1回文件。当我以编程方式更改文件的内容时,它似乎不喜欢它。

这是我的python代码片段,它改变了文件的内容,它嵌套在一个循环中:


scan_cmd = AllCommands.start_scan

# generate the key cmd packet for engine to start listening to incoming switches

#
# with open("../data/switches_debug.sf") as sw_file:
#    switch_ids = [i.split(",")[0] for i in sw_file.readlines()]
#    #print(switch_ids)

packet = CommandPacket(0xFFFFFF, scan_cmd)
content = ""




can_edit_file = False
while not can_edit_file:
    with open("../data/cmd.sf", "r") as cmd_file:
        try:
            content = int(cmd_file.readlines()[0])
        except ValueError:
        # means gui has already written to file and is in the form of x,x,x,...,x
        # 12345,67,8
        # The beginning of this function should just check to see if
        # file content IS NOT -1 in order to prevent engine and gui
        # writing to the file at the same time
        #
        # So if GUI has written to file and in the
        # form of csv, it is obviously not -1
        #
        # assign content a value that is not -1
        content = 0

        if content == -1:
            can_edit_file = True

msg = "Begin Listening... [%s]" % packet.hex()
print(msg)
content = ','.join(str(x) for x in packet.plist)

# open as 'w' to overrite content of file
with open("../data/cmd.sf", "w") as cmd_file:
    cmd_file.write(content)

print("Wrote [%s] to ../data/cmd.sf" % packet.hex())

同样,这是读取并检查文件是否已更改的 C++ 代码:

Scribe Cher("../data/cmd.sf");

for (;;) {
    std::cout << std::flush;
    // cpu_timer tmr;

    // loop forever and read from cmd.sf for instructions
    // if file contents is != -1 instruction from GUI is set; read and execute
    // upon successful instruction execution write '-1' to file

    // read contents of cmd.sf file
    bool file_is_ready = false;
    int u = 0;
    do{

      Cher.ReadFile();    // custome object that actually does the reading
      cmd_file = std::stoi(Cher.FileContents);   // Cher.FileContents is std::string

      //debugging section
      if(u % 10000 == 0){
    std::cout << std::flush;
    fmt::printf("File Contents: {%s}\n", Cher.FileContents);
      }

      if(cmd_file != -1){
    file_is_ready = true;
      }
      u++;

    }while(!file_is_ready);
}

Cher 实例属于 Scribe 对象,它是一个帮助程序类,用于控制对文件的读/写。初始化时,它会在类中设置一个重要成员,即文件路径。每个“Scribe”都分配给一个文件。

void Scribe::ReadFile(){
  std::string file_contents;
  std::vector<std::string> vstring;

  this->File.close();   //in case the file is opened
  if(!this->File.open(std::ios::in)){
    throw std::ios::failure("Unable to open file.");
    //std::cout << "Unable to Open" << std::endl;
  }

  this->File.clear();
  this->File.seekg(0, std::ios_base::beg);

  while(this->File >> file_contents){
    std::cout << "infinite loop" << std::endl;
    vstring.push_back(file_contents);
  }

//for(auto &i: vstring){
// std::cout << i << std::endl;
//
  this->FileContents = vstring[0];
  this->File.close();
}

这是我通过最初cmd.sf-1

File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
Segmentation Fault     //this is when I use the python gui to change file contents

标签: pythonc++c++14

解决方案


推荐阅读