文件互斥
通过linux下文件互 斥地打开,实现线程/进程互斥的访问资源,以此实现多线程编程。
值得注意的是,文件互斥的方式不但适用于多线程编程,还能实现多进程之间的交互。
lock.h
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> void initlock (const char* lockfile); void lock (const char* lockfile); void unlock (const char* lockfile);
lock.c
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> void initlock (const char* lockfile) { int i; unlink(lockfile); } void lock (const char* lockfile) { int fd; //添加了O_EXCL之后,没有文件则创建文件,有文件则打开失败进入while循环知道这个文件删除 while((fd = open(lockfile, O_RDONLY | O_CREAT | O_EXCL)) < 0) sleep(1); close(fd); } void unlock (const char* lockfile) { unlink(lockfile); }
利用这个文件互斥来实现之前的哲学家进餐问题,只是把互斥锁的部分换成这个lock
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include "lock.h" #define N 5 // five philosopher #define T_EAT 5 #define T_THINK 5 #define N_ROOM 4 //同一时间只允许4人用餐 #define left(phi_id) (phi_id+N-1)%N #define right(phi_id) (phi_id+1)%N enum { think , hungry , eat }phi_state[N]; static char* chopstick[N] = {"chopstick0", "chopstick1", "chopstick2", "chopstick3", "chopstick4"}; void thinking(int id){ sleep(T_THINK); printf("philosopher[%d] is thinking...\n", id); } void eating(int id){ sleep(T_EAT); printf("philosopher[%d] is eating...\n", id); } void take_forks(int id){ //获取左右两边的筷子 //printf("Pil[%d], left[%d], right[%d]\n", id, left(id), right(id)); if((id&1) == 1){ lock(chopstick[left(id)]); lock(chopstick[right(id)]); } else{ lock(chopstick[right(id)]); lock(chopstick[left(id)]); } //printf("philosopher[%d] take_forks...\n", id); } void put_down_forks(int id){ printf("philosopher[%d] is put_down_forks...\n", id); unlock(chopstick[left(id)]); unlock(chopstick[right(id)]); } void* philosopher_work(void *arg){ int id = *(int*)arg; printf("philosopher init [%d] \n", id); while(1){ thinking(id); //sem_wait(&room); take_forks(id); //sem_post(&room); eating(id); put_down_forks(id); } } int main(){ pthread_t phiTid[N]; int i; int err; int *id=(int *)malloc(sizeof(int)*N); //initilize semaphore for (i = 0; i < N; i++) { initlock(chopstick[i]); } for(i=0; i < N; ++i){ //printf("i ==%d\n", i); id[i] = i; err = pthread_create(&phiTid[i], NULL, philosopher_work, (void*)(&id[i])); //这种情况生成的thread id是0,1,2,3,4 if (err != 0) printf("can't create process for reader\n"); } while(1); exit(0); return 0; }
利用这个文件锁,可以实现单一时间保证一个系统中只有一个实例.