Что-то не так с IPC - PullRequest
       91

Что-то не так с IPC

0 голосов
/ 30 апреля 2020

Есть процессы: родитель и потомок, а потомок создается fork(). Я использую mmap() для реализации IP C между родительским процессом и дочерним процессом, и для общей памяти устанавливается структура SharedMessage. Вот его определение:

struct SharedMessage{
    bool should_stop_work = false;
    int mutex = 1;
    int total = 0;
    std::string s;
};

Теперь родительский процесс получит ввод данных от пользователя cin или getline(), а затем сохранит его в s в структуре. Дочерний процесс выполнит некоторую работу: проверите s, напечатайте его, если пользовательский ввод является строкой, и добавьте его к total в структуре, если пользовательский ввод является числом. Когда total достигает 100, оба процесса завершаются. Поскольку переменная типа структуры является общим ресурсом, существуют также P() и V().

Проблема заключается в следующем: когда дочерний процесс обращается к общей памяти, что хранится в s в структуре что-то запутано, на экране напечатан грязный код. Но то, что родительский доступ - это ожидаемые данные, что я ввожу только сейчас.

Что я сделал:

  1. Проверьте остальные данные в структуре, когда это дочерний процесс. Я обнаружил, что только строковая переменная s неверна, остальное - именно то, что я и ожидал.
  2. Проверьте, не является ли размер общей памяти неправильным, но это не так.
  3. Тест с другим cpp файлом. Я определил структуру, которая содержит только строковую переменную, но она отлично работает. Ничего плохого не произошло.
  4. Когда я переупорядочиваю элементы в структуре:
struct SharedMessage{
    std::string s;
    bool should_stop_work = false;
    int mutex = 1;
    int total = 0;
};

Выдается исключение: free (): неверный указатель

Полный код:

#include <iostream>
#include <unistd.h>
#include <cstring>
#include <sys/mman.h>

using namespace std;


struct SharedMessage{
    string s;
    bool should_stop_work = false;
    int mutex = 1;
    int total = 0;
};

void *create_shared_memory(size_t size){
    int protection = PROT_READ | PROT_WRITE;
    int visibility = MAP_SHARED | MAP_ANONYMOUS;
    return mmap(NULL, size, protection, visibility, -1, 0);
}


void P(SharedMessage *sm){
    --(*sm).mutex;
    while((*sm).mutex<0){
    }
}

void V(SharedMessage *sm){
    ++(*sm).mutex;
}

void handle_parent_process(SharedMessage *sm){
    P(sm);
    cout << "This is parent process, input data please: ";
    cin >> (*sm).s;
    V(sm);
}

void handle_child_process(SharedMessage *sm){
    P(sm);
    bool is_digital = true;
    const char *c = (*sm).s.c_str();
    for (int i = 0; i < (*sm).s.length(); ++i){
        if (!isdigit(*(c + i))){
            is_digital = false;
            break;
        }
    }
    if ((*sm).s.length() == 0){
        is_digital = false;
    }

    if (is_digital){
        (*sm).total += stoi((*sm).s);
        cout << (*sm).total << endl;
        if ((*sm).total > 100){
            (*sm).should_stop_work = true;
        }
    } else{
        cout << (*sm).s << endl;
    }
    (*sm).s = "";
    V(sm);
}



int main(){
    SharedMessage shared_message;
    void *shmem = create_shared_memory(sizeof(SharedMessage));
    memcpy(shmem, &shared_message, sizeof(SharedMessage));

    int pid = fork();

    SharedMessage *sm = (SharedMessage *)shmem;
    if (pid == 0){
        while (!(*sm).should_stop_work){
            sleep(0.05f);
            handle_child_process(sm);
        }
    } else {
        while(!(*sm).should_stop_work){
            sleep(0.12f);
            handle_parent_process(sm);
        }
    }
    if (pid == 0){
        cout << "This is child process, and my work done!" << endl;
    }

    return 0;
}

Вот вывод:


This is parent process, input data please: sssssss
���?

This is parent process, input data please: test
���
This is parent process, input data please: 

Надеюсь, кто-нибудь может мне помочь. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...