• 【Linux线程同步专题】五、进程间同步


    在这里插入图片描述

    欢迎关注博主 Mindtechnist 或加入【Linux C/C++/Python社区】一起探讨和分享Linux C/C++/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。



    专栏:《Linux从小白到大神》 | 系统学习Linux开发、VIM/GCC/GDB/Make工具、Linux文件IO、进程管理、进程通信、多线程等,请关注专栏免费学习。


    1. 互斥量mutex

    进程间也可以通过互斥锁来达到同步的目的。在pthread_mutex_init初始化之前需要修改属性为进程间共享。

    1.1 互斥量属性对象的创建与销毁

    • 头文件及函数原型
    #include 
    
    int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
    int pthread_mutexattr_init(pthread_mutexattr_t *attr);
    
    • 1
    • 2
    • 3
    • 4
    • 函数描述

      • The pthread_mutexattr_destroy() function shall destroy a mutex attributes object; the object becomes, in effect, uninitialized.
      • The pthread_mutexattr_init() function shall initialize a mutex attributes object attr with the default value for all of the attributes defined by the implementation.
    • 函数参数

      • attr:互斥量属性对象
    • 函数返回值

      Upon successful completion, pthread_mutexattr_destroy() and pthread_mutexattr_init() shall return zero; otherwise, an error number shall be returned to indicate the error.

    1.2 属性的设置与获取

    • 头文件及函数原型
    #include 
    
    int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared);
    int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
    
    • 1
    • 2
    • 3
    • 4
    • 函数描述

      • The pthread_mutexattr_getpshared() function shall obtain the value of the process-shared attribute from the attributes object referenced by attr.
      • The pthread_mutexattr_setpshared() function shall set the process-shared attribute in an initialized attributes object referenced by attr.
    • 函数参数

      • attr
      • pshared
    • 函数返回值

      Upon successful completion, pthread_mutexattr_setpshared() shall return zero; otherwise, an error number shall be returned to indicate the error. Upon successful completion, pthread_mutexattr_getpshared() shall return zero and store the value of the process-shared attribute of attr into the object referenced by the pshared parameter. Otherwise, an error number shall be returned to indicate the error.

    2. 文件锁

    借助fcntl()函数来实现锁机制,操作文件的进程没有获得锁时,可以打开,但无法执行read和write操作。文件锁具有读写锁的特点,写独占,读共享,写优先级高。

    • 头文件及函数原型
    #include 
    #include 
    
    int fcntl(int fd, int cmd, ... /* arg */ );
    
    • 1
    • 2
    • 3
    • 4
    • 函数描述

      fcntl() performs one of the operations described below on the open file descriptor fd. The operation is determined by cmd. 获取、设置文件访问控制属性。

    • 函数参数

      • fd:文件描述符
      • cmd:
        • F_SETLK (struct flock *):设置文件锁trylock
        • F_SETLKW (struct flock *):设置文件锁lock
        • 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 长度,0表示整个文件加锁 */
      	pid_t l_pid;     /* PID of process blocking our lock (F_GETLK only) 持有该锁的进程ID */
      	...
      };
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 函数返回值

      • For a successful call, the return value depends on the operation:

        • F_DUPFD The new descriptor.

        • F_GETFD Value of flags.

        • F_GETFL Value of flags.

        • F_GETLEASE Type of lease held on file descriptor.

        • F_GETOWN Value of descriptor owner.

        • F_GETSIG Value of signal sent when read or write becomes possible, or zero for traditional SIGIO behavior.

          All other commands Zero.

      • On error, -1 is returned, and errno is set appropriately.

    用法示例:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define _FILE_PATH_ "/home/qq/dm/daemon/test.lock"
    
    int main(int argc, char* argv[])
    {
        int fd = open(_FILE_PATH_, O_RDWR | O_CREAT, 0644);
        if(fd < 0)
        {
            perror("open err");
            return -1;
        }
        struct flock lk;
        lk.l_type = F_WRLCK;
        lk.l_whence = SEEK_SET;
        lk.l_start = 0;
        lk.l_len = 0;
        if(fcntl(fd, F_SETLK, &lk) < 0)
        {
            perror("lock err");
            exit(1);
        }
        while(1)
        {
            printf("pid: %d\n", getpid());
            sleep(1);
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    编译运行

    在这里插入图片描述

    此时我们再开一个终端运行上面的程序

    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述


  • 相关阅读:
    [Vue]中数组的操作用法
    开启未来创新之门:.NET Conf China 2023 精彩回顾及资料下载
    Shell编程从看懂到看开①(Shell概述、变量、运算符、条件判断)
    Stream.toList()和Collectors.toList()的性能比较
    短视频特效背景视频去哪找?三大平台助你轻松搞定!
    VAE(变分自动编码器)
    SwiftUI 原生或利用 Vision 检测限定高度的 Text 视图能否完整显示文本的方法
    基于SSM的美妆购物平台
    全球与中国吸油烟机行业市场规模调研及未来前瞻报告2022-2028年
    (十五)VBA常用基础知识:正则表达式的使用
  • 原文地址:https://blog.csdn.net/qq_43471489/article/details/127417989