#include #include #include #include struct shared_data { pthread_mutex_t mutex; int counter; }; struct shm_shared_data { int shm_id; struct shared_data *shared_data; }; void increment_counter(struct shared_data *data) { for (int i = 0; i < 100000; i++) { if (pthread_mutex_lock(&data->mutex) != 0) { perror("pthread_mutex_lock"); } data->counter++; if (pthread_mutex_unlock(&data->mutex) != 0) { perror("pthread_mutex_unlock"); } } } struct shm_shared_data shared_data_open() { key_t key = ftok("shmfile", 65); // Generate a key for the shared memory segment // Create a shared memory segment int shm_id = shmget(key, sizeof(struct shared_data), 0666 | IPC_CREAT); if (shm_id == -1) { perror("shmget"); exit(EXIT_FAILURE); } // Attach the shared memory segment to the address space of the process struct shared_data *shared_data = shmat(shm_id, NULL, 0); if (shared_data == (void*)-1) { perror("shmat"); exit(EXIT_FAILURE); } struct shm_shared_data shm_shared_data = { .shm_id = shm_id, .shared_data = shared_data }; return shm_shared_data; } void shared_data_close(struct shm_shared_data shm_data) { // Detach the shared memory segment if (shmdt(shm_data.shared_data) == -1) { perror("shmdt"); exit(EXIT_FAILURE); } } void *thread_callback(void *p) { struct shm_shared_data shm_data = shared_data_open(); increment_counter(shm_data.shared_data); shared_data_close(shm_data); return NULL; } int main() { struct shm_shared_data shm_data = shared_data_open(); pthread_mutexattr_t mutex_attr; pthread_mutexattr_init(&mutex_attr); pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED); if (pthread_mutex_init(&shm_data.shared_data->mutex, &mutex_attr) < 0) { printf("Failed to initialise mutex\n"); return -1; } pthread_t thread1; pthread_create(&thread1, NULL, thread_callback, NULL); pthread_t thread2; pthread_create(&thread2, NULL, thread_callback, NULL); pthread_join(thread1, NULL); pthread_join(thread2, NULL); printf("Counter is %d\n", shm_data.shared_data->counter); shared_data_close(shm_data); // Remove the shared memory segment if (shmctl(shm_data.shm_id, IPC_RMID, NULL) == -1) { perror("shmctl"); exit(EXIT_FAILURE); } return 0; }