(四十四)进程间的锁

一、进程间的pthread_mutex

通过改变互斥锁的属性,使之成为进程间的锁

#include <pthread.h>

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

pshared参数:
线程锁:PTHREAD_PROCESS_PRIVATE
进程锁:PTHREAD_PROCESS_SHARED
默认情况是线程锁

  
  
  通过例子学习,更直观:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>

struct mt {
    int num;
    pthread_mutex_t mutex;          //互斥锁
    pthread_mutexattr_t mutexattr;  //互斥锁的属性(可以设置为进程锁)
};

int main(void)
{
    int fd, i;
    struct mt *mm;//创建结构体指针,之后将指向共享空间
    pid_t pid;
    fd = open("mt_test", O_CREAT | O_RDWR, 0777);//创建一个临时文件
    /*  ftruncate(fd, sizeof(*mm));
     *  将文件fd的大小修改为sizeof(*mm) 
     *  不需要write,文件里初始值为0 */
    ftruncate(fd, sizeof(*mm));

    /* 映射空间,进程共享空间内的内容,将该结构体指针指向该空间 */
    mm = mmap(NULL, sizeof(*mm), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    close(fd);
    memset(mm, 0, sizeof(*mm));


    /* 初始化 互斥对象 属性*/
    pthread_mutexattr_init(&mm->mutexattr);
    /*
     * 设置互斥对象为PTHREAD_PROCESS_SHARED共享
     * 即可以在多个进程的线程访问
     * PTHREAD_PROCESS_PRIVATE为同一进程的线程共享
     */
    pthread_mutexattr_setpshared(&mm->mutexattr,PTHREAD_PROCESS_SHARED);

    /* 用之前设置的属性,初始化互斥锁 */
    pthread_mutex_init(&mm->mutex, &mm->mutexattr);


    pid = fork();
    if (pid == 0)
    {//子进程中
        /* 加10次。相当于加10 */
        for (i=0;i<10;i++)
        {
            pthread_mutex_lock(&mm->mutex);
                (mm->num)++;
                printf("In child num++:%d\n",mm->num);
            pthread_mutex_unlock(&mm->mutex);
            sleep(1);
        }
    }
    else if (pid > 0) 
    {//父进程中
        /* 父进程完成x+2,加10次,相当于加20 */
        for (i=0; i<10; i++)
        {
            pthread_mutex_lock(&mm->mutex);
                mm->num += 2;
                printf("In father num+=2:%d\n",mm->num);
            pthread_mutex_unlock(&mm->mutex);
            sleep(1);
        }
        //阻塞等待回收子进程
        wait(NULL);
    }

    pthread_mutex_destroy(&mm->mutex);
    pthread_mutexattr_destroy(&mm->mutexattr);
    /* 父子均需要释放*/
    munmap(mm,sizeof(*mm));
    unlink("mt_test");
    return 0;
}

二、文件锁

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 <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.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 = SEEK_SET; 
    f_lock.l_start = 0;         
    f_lock.l_len = 0;   //0表示整个文件加锁
    fcntl(fd, F_SETLKW, &f_lock);//通过fcntl设置文件锁

    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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值