Попытка чтения из файлового дескриптора в буфер не удалась при доступе вне объекта - PullRequest
0 голосов
/ 20 июня 2019

Я никогда не работал с файловыми дескрипторами, и меня немного смущает это поведение. Я также довольно плохо знаком с параллелизмом, и документации для этих функций довольно не хватает.

Мой конструктор MessageReciever открывает pty. При вызове сообщения приема, как я понимаю, код разветвляется. Мастер должен нажать следующее условие и вернуться из функции. Я знаю, что это происходит потому, что код в main не блокируется. Ребенок читает в дескрипторе файла, преобразует его в строку и сохраняет его в векторе. В настоящее время я печатаю буфер напрямую, но я также могу напечатать последний элемент в векторе, и он действует в основном так же. Однако, когда я пытаюсь получить доступ к этому вне класса, в основном, я ничего не получаю. Я думал, что это может быть проблемой параллелизма, но я не совсем уверен, как ее решить.

КОД

#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <stdio.h>
#include <util.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string>
#include <vector>

class MessageReceiver
{
  public:
  MessageReceiver()
  {
    openpty(&master, &slave, NULL, NULL, NULL);
  }

  ~MessageReceiver()
  {
    close(master);
    close(slave);
  }

  void receiveMessage()
  {
    pid_t pid = fork();
    printf("PID = %d\n",pid);
    if(pid > 0)
    {
      fd_set rfds;
      struct timeval tv;
      tv.tv_sec = 0;
      tv.tv_usec = 0;
      char buf[4097];
      ssize_t size;
      size_t count = 0;

      while (1)
      {
        if (waitpid(pid, NULL, WNOHANG) == pid) 
        {
          break;
        }
        FD_ZERO(&rfds);
        FD_SET(master, &rfds);
        if (select(master + 1, &rfds, NULL, NULL, &tv)) 
        {
          size = read(master, buf, 4096);
          printf("Buffer = %s", buf);
          messageBuffer.push_back(std::string(buf));
          buf[size] = '\0';
          count += size;
        }
      }

    }

  }

  std::string getLastMessage()
  {
    std::string s;
    if(messageBuffer.size() > 0)
    {
      s = messageBuffer.back();
    }
    else
    {
      s = "NULL";
    }
    return s;
  }

  private:
  int master, slave;
  std::vector<std::string> messageBuffer;
};

int main()
{
  MessageReceiver m;
  m.receiveMessage();
  std::string lastMessage = m.getLastMessage();
  printf("Printing message buffer:\n");
  for(;;)
  {
    if(m.getLastMessage() != lastMessage)
    {
      printf("Message: %s\n", m.getLastMessage().c_str());
    }
  }
  return 0;
}

Начальный выход

PID = 8170
PID = 0
Printing message buffer:

Дополнительный вывод при передаче эхо-сообщения в pty

Buffer = hello
...