BabyRage Δημοσ. 26 Απριλίου 2017 Δημοσ. 26 Απριλίου 2017 Ποιά είναι η διαφορά μεταξύ των παρακάτω τρόπων ορισμού κοινής μνήμης μεταξύ δύο διεργασιών? #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <semaphore.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #define MAX_LEN 10000 struct region { int len; char buf[MAX_LEN]; }; int fd; int main(void){ //Create shared memory fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if (fd == -1) printf("Error: shm_open\n"); //Expand to meet the desirable size if (ftruncate(fd, MAX_LEN*sizeof(struct region)) == -1) printf("Error: ftruncate\n"); pid_t pid = fork(); if (pid == 0){ struct region * ptr = mmap(NULL, MAX_LEN*sizeof(struct region), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) printf("Error\n"); memset(ptr, 0, 50*sizeof(struct region)); usleep(1500000); ptr[33].len = 42; }else if (pid > 0){ struct region * ptr = mmap(NULL, MAX_LEN*sizeof(struct region), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) printf("Error\n"); usleep(1000000); printf("Value before: %d\n", ptr[33].len); usleep(1000000); printf("Value after: %d\n", ptr[33].len); }else{ printf("Error: fork\n"); } return 0; } και χωρίς χρήση shm_open, με απλά την mmap (τα globals είναι ίδια): int main(void){ struct region * ptr = mmap(NULL, MAX_LEN*sizeof(struct region), PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED,-1,0); pid_t pid = fork(); if (pid == 0){ usleep(1500000); ptr[33].len = 42; }else if (pid > 0){ usleep(1000000); printf("Value before: %d\n", ptr[33].len); usleep(1000000); printf("Value after: %d\n", ptr[33].len); }else{ printf("Error: fork\n"); } return 0; } Αυτό το οποίο πιστεύω είναι ότι με την shm_open η κοινη μνήμη έχει "όνομα" ενώ στην mmap είναι ANONYMOUS. Δηλαδή, αν φτιάξω το παρακάτω τελειώς διαφορετικό εκτελέσιμο, τότε βλέπω τις αλλαγές που γίνονται: #define MAX_LEN 1000 struct region { int len; char buf[MAX_LEN]; }; int fd; int main(void){ //Create shared memory fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if (fd == -1) printf("Error: shm_open\n"); //struct region * ptr = mmap(NULL, MAX_LEN*sizeof(struct region), PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED,-1,0); struct region * ptr = mmap(NULL, MAX_LEN*sizeof(struct region), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) printf("Error\n"); while(1){ usleep(1000000); printf("Value: %d\n", ptr[33].len); } return 0; } Φοβάμαι να ρωτήσω στο stackoverflow, οπότε ρωτάω εδώ αν ξέρει κάνεις να διαφωτήσει.
solarpower Δημοσ. 26 Απριλίου 2017 Δημοσ. 26 Απριλίου 2017 Καμία σχέση! Το ένα έχει να κάνει με μνήμη ως αρχείο για όποιον είναι στο ίδιο group id, ενώ το άλλο έχει να κάνει με την virtual address space of the calling process. Απλά χρησιμοποιείς και τα δύο, έτσι ώστε το δεύτερο για να φτιάξεις ένα view στο πρώτο.
BabyRage Δημοσ. 26 Απριλίου 2017 Μέλος Δημοσ. 26 Απριλίου 2017 Καμία σχέση! Το ένα έχει να κάνει με μνήμη ως αρχείο για όποιον είναι στο ίδιο group id, ενώ το άλλο έχει να κάνει με την virtual address space of the calling process. Απλά χρησιμοποιείς και τα δύο, έτσι ώστε το δεύτερο για να φτιάξεις ένα view στο πρώτο. Με την shm_open δηλαδη, ορίζεις μια κοινή μνήμη με ένα συγκεκριμένο όνομα, παίρνεις τον file descriptor σου, και που όπως λέει και το man page της shm_open, η κοινή μνήμη είναι ένα: A POSIX shared memory object is in effect a handle which can be used by unrelated processes to mmap(2) the same region of shared memory είναι απλά έναν αντικείμενο που μπορεί να μοιραστεί μεταξύ διεργασίών, σαν ένα αρχείο. Στον δεύτερο τρόπο, η κοινή μνήμη που μοιράζεται ζει στο virtual space του πατέρα εν προκειμένω, όπως καταλαβαίνω, και το mapping που κάνει το παιδί βλέπει και εφαρμόζει αλλαγές που συγχρονίζονται με την κοινή μνήμη του πατέρα του: (από τον man page της mmap) MAP_SHARED Share this mapping. Updates to the mapping are visible to other processes mapping the same region, and (in the case of file-backed mappings) are carried through to the underlying file. (To precisely control when updates are carried through to the underlying file requires the use of msync(2).) Η κοινή μνήμη με την shm_open λοιπόν σε ποιό virtual space ζει; Δεδονένου ότι οι κλήσεις shm_open και ftruncate() γίνονται από τον πατέρα, η κοινή μνήμη ζει στο virtual space του πατέρα, απλά είναι πιο εύκολα προσβάσιμη από την στιγμή που έχει και file descriptor που μπορεί να χρησιμοποιηθεί για mapping και από άλλες διεργασίες σε άλλα εκτελέσιμα. Οπότε γιατί καμία σχέση δεν έχουν μεταξύ τους;
solarpower Δημοσ. 27 Απριλίου 2017 Δημοσ. 27 Απριλίου 2017 Εγώ απάντησα σε σχέση με το ANONYMOUS. Το ANONYMOUS mmap() ζητάει από τη μνήμη του process και μόνο, άρα δεν σχετίζεται με αυτό που έχει να κάνει με οποιοδήποτε process, όπως το shm_open.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα