Есть процессы: родитель и потомок, а потомок создается 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
в структуре что-то запутано, на экране напечатан грязный код. Но то, что родительский доступ - это ожидаемые данные, что я ввожу только сейчас.
Что я сделал:
- Проверьте остальные данные в структуре, когда это дочерний процесс. Я обнаружил, что только строковая переменная
s
неверна, остальное - именно то, что я и ожидал. - Проверьте, не является ли размер общей памяти неправильным, но это не так.
- Тест с другим cpp файлом. Я определил структуру, которая содержит только строковую переменную, но она отлично работает. Ничего плохого не произошло.
- Когда я переупорядочиваю элементы в структуре:
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:
Надеюсь, кто-нибудь может мне помочь. Спасибо!