|
#include <stdio.h> |
|
#include <stdlib.h> |
|
|
|
#include <unistd.h> |
|
#include <pthread.h> |
|
#include <sys/mman.h> |
|
#include <sys/stat.h> |
|
#include <sys/types.h> |
|
#include <fcntl.h> |
|
|
|
#define SHM_NAME "pshared_mutex1" |
|
#define INCRE_NUM 100000 |
|
|
|
struct pshared_resource { |
|
int* counter; // a counter on share memory |
|
int shm_fd; |
|
size_t shm_size; |
|
|
|
// pthread_mutex_t* pmutex; // process shared mutex |
|
pthread_mutex_t pmutex; // process shared mutex |
|
pthread_mutexattr_t mutex_attr; |
|
}; |
|
|
|
void resource_init(struct pshared_resource* this){ |
|
this->shm_fd = shm_open(SHM_NAME, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR); |
|
if( this->shm_fd == -1 ){ |
|
perror("shm_open error"); |
|
} |
|
this->shm_size = sizeof(int); |
|
ftruncate(this->shm_fd, this->shm_size); |
|
this->counter = mmap(NULL, this->shm_size, PROT_READ|PROT_WRITE, MAP_SHARED, this->shm_fd, 0); |
|
if( (int)this->counter == -1 ){ |
|
perror("mmap error"); |
|
} |
|
*(this->counter) = 0; |
|
|
|
pthread_mutexattr_init(&(this->mutex_attr)); |
|
pthread_mutexattr_setpshared(&(this->mutex_attr), PTHREAD_PROCESS_SHARED); |
|
// this->pmutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t)); |
|
// pthread_mutex_init(this->pmutex, &(this->mutex_attr)); |
|
pthread_mutex_init(&(this->pmutex), &(this->mutex_attr)); |
|
} |
|
|
|
void resource_destroy(struct pshared_resource* this){ |
|
munmap(this->counter, this->shm_size); |
|
close(this->shm_fd); |
|
shm_unlink(SHM_NAME); |
|
|
|
// pthread_mutex_destroy(this->pmutex); |
|
// free(this->pmutex); |
|
pthread_mutex_destroy(&(this->pmutex)); |
|
pthread_mutexattr_destroy(&(this->mutex_attr)); |
|
} |
|
|
|
void increment(struct pshared_resource* r, pid_t pid){ |
|
// lock |
|
// pthread_mutex_lock(r->pmutex); |
|
pthread_mutex_lock(&(r->pmutex)); |
|
// critical section |
|
int count = (*((volatile int*)(r->counter)))++; |
|
printf("[%d] counter = %d\n", pid, count); |
|
// sleep(2); |
|
// unlock |
|
// pthread_mutex_unlock(r->pmutex); |
|
pthread_mutex_unlock(&(r->pmutex)); |
|
} |
|
|
|
int main(){ |
|
struct pshared_resource resource; |
|
resource_init(&resource); |
|
|
|
pid_t child_pid = fork(); |
|
if( child_pid > 0 ){ |
|
// parent |
|
pid_t parent_pid = getpid(); |
|
for( int i = 0; i < INCRE_NUM; i++ ){ |
|
increment(&resource, parent_pid); |
|
} |
|
} |
|
else if( child_pid == 0 ){ |
|
// child |
|
// sleep(1); |
|
pid_t child_pid = getpid(); |
|
for( int i = 0; i < INCRE_NUM; i++ ){ |
|
increment(&resource, child_pid); |
|
} |
|
} |
|
else{ |
|
perror("pthread failed"); |
|
} |
|
|
|
resource_destroy(&resource); |
|
|
|
return 0; |
|
} |