Witam
- Mmap gdy mu się poda file deskryptor i ustawi obojętnie jaką flagę - nawet
MAP_SHARED
- odwzorowuje to co znajduje się w pliku na przestrzeń adresową procesu.
W przypadku plików z katalogu /dev jeżeli w kernel spejsie drivera jest zaimplementowana funkcja mmap która następnie jest przekazywana do file operations tablicy podczas rejestracji drivera można uzyskać nawet odwzorowanie w przestrzeni adresowej procesu mapy pamięci urządzenia zewnętrznego podłączonego np. przez GPIO do procesora.
Ale tutaj mam pytanie. To wyżej sprawia że zżeramy pamięć RAM, czy mam rację? Jakbyśmy tego wyżej nie robili tylko za każdym razem otwierali plik (wywołanie syscalla open), odczytywali/zapisywali dane (kolejne syscalle) to mielibyśmy więcej pamięci RAM, ale za to wolniejsze dostępy do interesujących nas danych przez to że syscalle leciałyby do kernel spejsa i głównie po to się używa mmap aby mieć szybszy dostęp, czy mam rację?
- Gdy mamy proces z którego forkujemy inny proces to zauważyłem że nie trzeba używać w ogóle shm_open, shm_unlink do tworzenia współdzielonej pamięci, wystarczy użyć tylko mmap:
static int* counterGlob = nullptr;
void SemaphoreTest()
{
#ifdef LINUX_USED
cout << "\nSemaphoreTest()" << endl;
counterGlob = (int*)mmap(NULL, sizeof(counterGlob), PROT_WRITE | PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if(counterGlob == MAP_FAILED)
{
perror("Mapping failed");
exit(EXIT_FAILURE);
}
int counter = 0;
pid_t pid = fork();
if (pid == 0)
{
cout << "Child process with pid " << getpid() << ", local counter = " << ++counter << endl;
cout << "Child process with pid " << getpid() << ", global counter = " << ++*counterGlob << endl;
this_thread::sleep_for(chrono::milliseconds(2000));
exit(0);
}
else if (pid > 0)
{
cout << "Parent process with pid " << getpid() << ", local counter = " << ++counter << endl;
int status = 0;
pid_t pid = wait(&status);
cout << "Child process with pid " << pid << " exited with code " << status
<< " in parent context with pid " << getpid() << endl;
cout << "Parent process with pid " << getpid() << ", global counter = " << ++*counterGlob << endl;
}
else
cout << "Fork failed " << endl;
if(munmap(counterGlob, sizeof(counterGlob)) == -1)
{
perror("unmapping failed");
exit(EXIT_FAILURE);
}
exit(0);
#endif
}
Stąd mój wniosek, że dodatkowego interfejsu shm_open, shm_unlink używa się tylko gdy mamy procesy które nie powstały z forka, wtedy nie da się użyć tylko mmapy do stworzenia pamięci współdzielonej i stąd potrzeba tego dodatkowego interfejsu, mam rację?