Skip to content

Instantly share code, notes, and snippets.

@cwshu
Created June 26, 2016 11:28
Show Gist options
  • Save cwshu/bbf6bbbe41a645c8251ac741c4e9a2f8 to your computer and use it in GitHub Desktop.
Save cwshu/bbf6bbbe41a645c8251ac741c4e9a2f8 to your computer and use it in GitHub Desktop.
有 bug 的 process shared mutex
#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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment