文件互斥

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

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

时间: 2024-08-26 10:42:09

文件互斥的相关文章

Linux文件锁学习-flock, lockf, fcntl

参考  linux中fcntl().lockf.flock的区别 这三个函数的作用都是给文件加锁,那它们有什么区别呢? 首先flock和fcntl是系统调用,而lockf是库函数.lockf实际上是fcntl的封装,所以lockf和fcntl的底层实现是一样的,对文件加锁的效果也是一样的.后面分析不同点时大多数情况是将fcntl和lockf放在一起的. 下面首先看每个函数的使用,从使用的方式和效果来看各个函数的区别. 1. flock l 函数原型 #include<sys/file.h> i

linux下多线程编程

最近研究mysql源码,各种锁,各种互斥,好在我去年认真学了<unix环境高级编程>, 虽然已经忘得差不多了,但是学过始终是学过,拿起来也快.写这篇文章的目的就是总结linux 下多线程编程,作为日后的参考资料. 本文将介绍linux系统下多线程编程中,线程同步的各种方法.包括: 互斥量(mutex) 读写锁 条件变量 信号量 文件互斥 在介绍不同的线程同步的方法之前,先简单的介绍一下进程和线程的概念, 它们的优缺点,线程相关的API,读者——写者问题和哲学家就餐问题. 基础知识 1. 进程和

文件锁-fcntl flock lockf

这三个函数的作用都是给文件加锁,那它们有什么区别呢? 首先flock和fcntl是系统调用,而lockf是库函数.lockf实际上是fcntl的封装,所以lockf和fcntl的底层实现是一样的,对文件加锁的效果也是一样的.后面分析不同点时大多数情况是将fcntl和lockf放在一起的. 下面首先看每个函数的使用,从使用的方式和效果来看各个函数的区别. 1. flock l 函数原型 #include<sys/file.h> int flock(int fd, int operation); 

Nginx之进程间的通信机制(信号、信号量、文件锁)

1. 信号 Nginx 在管理 master 进程和 worker 进程时大量使用了信号.Linux 定义的前 31 个信号是最常用的,Nginx 则通过重定义其中一些信号的处理方法来使用吸纳后,如接收到 SIGUSR1 信号就意味着需要重新打开文件. 使用信号时 Nginx 定义了一个 ngx_signal_t 结构体用于描述接收到的信号时的行为: typedef struct { // 需要处理的信号 int signo; // 信号对应的字符串名称 char *signame; // 这个

最佳vim技巧

最佳vim技巧----------------------------------------# 信息来源----------------------------------------www.vim.org         : 官方站点comp.editors        : 新闻组http://www.newriders.com/books/opl/ebooks/0735710015.html : Vim书籍http://vimdoc.sourceforge.net/cgi-bin/vim

线程------竞争,互斥量---多线程对同一文件读写问题

当多个控制线程共享相同的内存时呢,需要确保每个线程看到一致的数据视图. 如果每个线程使用的变量都是其他线程不会读取和修改,那么就不存在一致性的问题. 线程互斥接口用来保护数据,用于确保同一时间只有一个线程访问数据. 互斥:限制代码---独占 很久以前: 下面程序存在竞争问题的哟,当创建20个线程,每个线程都对同一个文件进行读写操作,有可能发生N个线程同时对文件进行打开和读操作,在写的过程可能会对同一个数重复进行+1操作.比如说读到  1, 然后N个线程取到1 并对1这个数做+1操作. /* 实现

TRTOS +TQFS多个任务同时读写文件的互斥操作

#include <Include.h> #include <TQFS_File.h> #include <stdlib.h> /******************************************************************************* Func:删除文件标准文件路径 .eg /example/新建文件.txt Date:2014-7-27 Note:FileSize=0时为不确定文件长度 **************

iOS并发编程笔记,包含GCD,Operation Queues,Run Loops,如何在后台绘制UI,后台I/O处理,最佳安全实践避免互斥锁死锁优先级反转等,以及如何使用GCD监视进程文件文件夹,并发测试的方案等

iOS并发编程笔记,包含GCD,Operation Queues,Run Loops,如何在后台绘制UI,后台I/O处理,最佳安全实践避免互斥锁死锁优先级反转等,以及如何使用GCD监视进程文件文件夹,并发测试的方案等 线程 使用Instruments的CPU strategy view查看代码如何在多核CPU中执行.创建线程可以使用POSIX 线程API,或者NSThread(封装POSIX 线程API).下面是并发4个线程在一百万个数字中找最小值和最大值的pthread例子: #import

文件传输项目模块2互斥与同步

#ifndef LOCKER_H #define LOCKER_H #include<exception> #include<pthread.h> #include<semaphore.h>//信号量头文件 #include<iostream> using namespace std; //封装信号量的类 class sem { public: //创建信号量 sem() { if( sem_init(&m_sem, 0, 0) != 0 )//第二