文件互斥

通过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;
}

利用这个文件锁,可以实现单一时间保证一个系统中只有一个实例.

posted @ 2015-07-10 18:43  Magnum Programm Life  阅读(592)  评论(0编辑  收藏  举报