Mam dość konkretne pytanie dotyczące współbieżnego programowania w C. Zrobiłem sporo badań na ten temat, ale widziałem kilka sprzecznych odpowiedzi, więc mam nadzieję na pewne wyjaśnienia. Mam program, który jest coś jak poniżej (przepraszam za podłużnego bloku kodu):równoczesny dostęp zmienny w c
typedef struct {
pthread_mutex_t mutex;
/* some shared data */
int eventCounter;
} SharedData;
SharedData globalSharedData;
typedef struct {
/* details unimportant */
} NewData;
void newData(NewData data) {
int localCopyOfCounter;
if (/* information contained in new data triggers an
event */) {
pthread_mutex_lock(&globalSharedData.mutex);
localCopyOfCounter = ++globalSharedData.eventCounter;
pthread_mutex_unlock(&globalSharedData.mutex);
}
else {
return;
}
/* Perform long running computation. */
if (localCopyOfCounter != globalSharedData.eventCounter) {
/* A new event has happened, old information is stale and
the current computation can be aborted. */
return;
}
/* Perform another long running computation whose results
depend on the previous one. */
if (localCopyOfCounter != globalSharedData.eventCounter) {
/* Another check for new event that causes information
to be stale. */
return;
}
/* Final stage of computation whose results depend on two
previous stages. */
}
Jest basen wątków obsługujących połączenia dla danych przychodzących, więc wielu wystąpień newData mogą być uruchomione w tym samym czasie . W środowisku wieloprocesorowym występują dwa problemy, o których wiem, że część kodu związana z obsługą kontrułowa jest poprawna: uniemożliwienie kompilatorowi buforowania współużytkowanej kopii licznika w rejestrze, aby inne wątki go nie widziały i wymuszenie CPU, aby zapisać pamięć licznika do pamięci w odpowiednim czasie, aby inne wątki mogły ją zobaczyć. Wolałbym nie używać wywołania synchronizacyjnego wokół czeków licznika, ponieważ częściowy odczyt wartości licznika jest akceptowalny (wygeneruje wartość inną niż kopia lokalna, co powinno wystarczyć do stwierdzenia, że zdarzenie miało miejsce). Czy byłoby wystarczające zadeklarowanie pola eventCounter w SharedData, aby było niestabilne, czy też muszę tu zrobić coś innego? Czy istnieje lepszy sposób na poradzenie sobie z tym?
Masz całkowitą pewność co do lokalnej kopii, właśnie naprawiłem ten błąd w moim tekście. – user98166