In generale, la posizione della memoria mutevole non sarà condivisa tra le applicazioni se non esplicitamente richiesta. Pertanto, quando libcnt
scrive su cnt_loads
, la pagina in cui cnt_loads
risiede sarà duplicata. Questo comportamento è noto come copy-on-write (COW). La stessa cosa accade se hai duplicato un processo con fork()
: il processo figlio non condividerà la memoria scrivibile con il genitore, se una qualsiasi scrittura avviene nella pagina "biforcuta", la pagina verrà duplicata.
Se si desidera utilizzare la memoria condivisa per la comunicazione tra processi, è necessario utilizzare memoria condivisa SystemV , POSIX memoria condivisa o mmap invece. Nota che questi metodi sono piuttosto persistenti, cioè dovrai rimuovere l'oggetto memoria condivisa dopo l'uso.
È possibile approssimare il comportamento originariamente desiderato utilizzando la memoria condivisa definendo __attribute__((constructor))
e __attribute__((destructor))
funzioni per la libreria condivisa. La funzione constructor
viene eseguita ogni volta che si apre la libreria, quindi è possibile utilizzarla per inizializzare / aprire la memoria condivisa e incrementare il conteggio del carico. Se mantieni anche un conteggio dei riferimenti (quante volte la libreria condivisa è aperta nel sistema adesso ) con destructor
--- oltre al conteggio del carico ---, puoi correttamente rimuovere la memoria condivisa quando il conteggio dei riferimenti scende a 0.
Si noti che l'uso della memoria condivisa per le comunicazioni tra processi richiede assolutamente qualche forma di mutua esclusione , ad esempio un semaforo o mutex. La mancata sincronizzazione corretta porterà a condizioni di gara (ad esempio, cosa succede quando due processi aprono la tua libreria esattamente nello stesso momento?). Puoi evitare l'esclusione reciproca se puoi incrementare / decrementare i contatori in un modo atomico . Vi raccomando di usare semafori inter-processo forniti dal sistema operativo anziché atomici, perché le operazioni atomiche sono difficili da utilizzare correttamente e il vostro problema non è affatto critico per le prestazioni (quindi non è necessario eseguire operazioni di blocco).