Ошибка сегментации возникает, когда программа C ++ читает файл, в то время как отдельный сценарий Python GUI пишет в тот же файл - PullRequest
0 голосов
/ 05 апреля 2019

В настоящее время я запускаю это на ОС Raspbian - Debian.

У меня есть две отдельные программы, работающие в унисон.У меня есть c ++ 'engine' и интерфейс python 'gui'.Я знаю, что, вероятно, есть гораздо лучшая практика, но в данный момент они общаются через простые файлы.По сути, графический интерфейс Python записывает в файл cmd.sf конкретный текст, а механизм затем декодирует тот же файл и выполняет все, что ему нужно.

Настройка довольно проста:

C ++ Engine:

Программа C ++ постоянно читает файл cmd.sf и остается в бесконечном цикле внутри механизма, если контекстфайла -1.В тот момент, когда файл изменяет движок, он должен проанализировать то, что в основном написано в графическом интерфейсе Python, и после успешного выполнения любого содержимого, которое подскажет движок, записывает обратно в файл -1

Python GUI

На стороне GUI это та же концепция, за исключением обратного.GUI также постоянно читает из файла cmd.sf и не продолжает писать ту же или другую инструкцию, пока не узнает, что механизм C ++ выполнен с его предыдущей инструкцией.Таким образом, он по существу проверяет файл, чтобы убедиться, что это что-то, НО -1

Проблема заключается в том, что, если я первоначально установил cmd.sf на -1, механизм C ++ делает то, что ему нужно для успешного выполнения,постоянно читая и проверяя содержимое файла.Тем не менее, в тот момент, когда я инструктирую графический интерфейс для изменения содержимого файла, механизм C ++ зависает, выдает ошибку сегмента и прерывает работу.

Однако я нашел что-то, что работает, и я не могу на всю жизньиз меня выяснить, почему.Если бы я должен был открыть cmd.sf в текстовом редакторе, таком как geany (я Raspbian) и изменить содержимое через редактор и сохранить его, это не вызовет ошибку segfault.Фактически механизм 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 с классом-помощником, который управляет чтением / записью в файлы.После инициализации он устанавливает один важный член в классе, и это путь к файлу. Каждый «Писец» назначается одному файлу.

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();
}

Вот пример выходного вывода stdout из терминала, когда язапустите это, изначально установив 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
...