进程间锁

帅比萌擦擦* 提交于 2020-01-15 01:30:29

目录

15.1 进程间pthread_mutex

15.2 文件锁



15.1 进程间互斥锁

直接上原语吧:

#include<pthread.h>

int pthread_mutexattr_init(pthread_mutexattr_t *attr);
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,int pshared);

pshared:
PTHREAD_PROCESS_PRIVATE:线程锁
PTHREAD_PROCESS_SHARED:进程锁

示例代码:

/*
    互斥量 实现 多进程 之间的同步 
*/
 
#include<unistd.h>
#include<sys/mman.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
 
struct mt
{
    int num;
    pthread_mutex_t mutex;
    pthread_mutexattr_t mutexattr;
};
 
 
int main(void)
{
    
    int i;
    struct mt* mm;
 
    pid_t pid;
 
    /*
    // 创建映射区文件
    int fd = open("mt_test",O_CREAT|O_RDWR,0777);
    if( fd == -1 ) 
    {
        perror("open file:"); 
        exit(1); 
    }
    ftruncate(fd,sizeof(*mm));
    mm = mmap(NULL,sizeof(*mm),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    close(fd);
    unlink("mt_test");
  */
 
    // 建立映射区
    mm = mmap(NULL,sizeof(*mm),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);
 
//    printf("-------before memset------\n");
    memset(mm,0x00,sizeof(*mm));
//   printf("-------after memset------\n");
 
    pthread_mutexattr_init(&mm->mutexattr);         // 初始化 mutex 属性
    pthread_mutexattr_setpshared(&mm->mutexattr, PTHREAD_PROCESS_SHARED);               // 修改属性为进程间共享
 
    pthread_mutex_init(&mm->mutex,&mm->mutexattr);      // 初始化一把 mutex 锁
    
    pid = fork();
    if( pid == 0 )          // 子进程
    {
        for( i=0; i<10;i++ )
        {
            pthread_mutex_lock(&mm->mutex);
            (mm->num)++;
            printf("-child--------------num++    %d\n",mm->num);
            pthread_mutex_unlock(&mm->mutex);
            sleep(1);
        }
    
    }
    else 
    {
        for( i=0;i<10;i++)
        {
            sleep(1); 
            pthread_mutex_lock(&mm->mutex);
            mm->num += 2;
            printf("--------parent------num+=2   %d\n",mm->num);
            pthread_mutex_unlock(&mm->mutex);
        
        }
        wait(NULL);
 
    }
    pthread_mutexattr_destroy(&mm->mutexattr);  // 销毁 mutex 属性对象
    pthread_mutex_destroy(&mm->mutex);          // 销毁 mutex 锁
 
    return 0;
}

15.2 文件锁

借助 fcntl 函数来实现文件锁。操作文件的进程没有获得锁时,可以打开,但无法执行 read,write 操作。

fcntl 函数:获取、设置文件访问控制属性。

原语函数:

  #include <unistd.h>
  #include <fcntl.h>
 
  int fcntl(int fd, int cmd, ... /* arg */ );

参数释义:
参数一:文件描述符
参数二:
F_SETLK(struct flock ); 设置文件锁 ( trylock )
F_SETLKW(struct flock
); 设置文件锁( lock ) W — wait
F_GETLK(struct flock*); 获取文件锁

参数三:

struct flock 
{
                            ...
        short l_type;    /* Type of lock: F_RDLCK,    F_WRLCK, F_UNLCK */
        short l_whence;  /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END */
        off_t l_start;   /* Starting offset for lock */
        off_t l_len;     /* Number of bytes to lock */
        pid_t l_pid;     /* PID of process blocking our lock (F_GETLK only) */
                             ...
};

代码示例:

#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
 
void sys_err(char*str)
{
    perror(str);
    exit(1);
}
 
 
int main(int argc,char *argv[])
{
    int fd;
    struct flock f_lock;
 
    if( argc< 2 )
    {
        printf("./a.out filename\n");
        exit(1);
    }
 
    if( ( fd = open(argv[1],O_RDWR)) < 0 )
        sys_err("open");
 
//    f_lock.l_type = F_WRLCK;          // 选用写锁
    f_lock.l_type = F_RDLCK;            // 选用读锁
    f_lock.l_whence = 0;
    f_lock.l_len = 0;                 // 0 表示整个文件加锁
 
    fcntl(fd,F_SETLKW,&f_lock);
    printf("get flock\n");
 
    sleep(10);
 
    f_lock.l_type = F_UNLCK;
    fcntl(fd,F_SETLKW,&f_lock);
    printf("un flock\n");
 
    close(fd);
    return 0;
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!