• 文件互斥


    通过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...
    ", id);
    }
    
    void eating(int id){
        sleep(T_EAT);
        printf("philosopher[%d] is eating...
    ", id);
    }
    
    void take_forks(int id){
        //获取左右两边的筷子
        //printf("Pil[%d], left[%d], right[%d]
    ", 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...
    ", id);
    }
    
    void put_down_forks(int id){
        printf("philosopher[%d] is put_down_forks...
    ", id);
        unlock(chopstick[left(id)]);
        unlock(chopstick[right(id)]);
    }
    
    void* philosopher_work(void *arg){
        int id = *(int*)arg;
        printf("philosopher init [%d] 
    ", 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
    ", 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
    ");
        }
    
        while(1);
        exit(0);
        return 0;
    }

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

  • 相关阅读:
    zstack(一)运行及开发环境搭建及说明(转载)
    ZStack深度试用:部署、架构与网络及其与OpenStack的对比
    saltops 安装及相关环境安装
    windows下安装rabbitmq的步骤详解
    SQLServer就更新并发处理的解决方案及测试!
    mysql 8.0.20安装教程,mysql详细安装教程
    .NET中的简单的并行
    四、VSCode调试vue项目
    三、使用VSCode配置简单的vue项目
    二、windows下搭建vue开发环境+IIS部署
  • 原文地址:https://www.cnblogs.com/biglucky/p/4636502.html
Copyright © 2020-2023  润新知