C语言提供的线程/进程间同步(锁)机制

2023-05-16

目录

 

一、C语言提供的线程间同步机制

1、互斥体 (Mutex)

2、读写锁(read-write locks)

3、条件变量 (conditional variables)

4、自旋锁(spinlocks)

 

二、C语言提供的进程间同步机制

1、信号量(semaphore)

2、信号SIGNAL

4、消息队列

5、共享内存

6、管道和套接字


一、C语言提供的线程间同步机制


1、互斥体 (Mutex)


描述:互斥体是比信号量更为简单是睡眠锁。
使用范围:最为常用。

#include <pthread.h>

/* Initialize a mutex. */
extern int pthread_mutex_init (pthread_mutex_t *__mutex,
                   const pthread_mutexattr_t *__mutexattr)
     __THROW __nonnull ((1));

/* Destroy a mutex.  */
extern int pthread_mutex_destroy (pthread_mutex_t *__mutex)
     __THROW __nonnull ((1));

/* Try locking a mutex.  */
extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)
     __THROWNL __nonnull ((1));

/* Lock a mutex.  */
extern int pthread_mutex_lock (pthread_mutex_t *__mutex)
     __THROWNL __nonnull ((1));

/* Unlock a mutex.  */
extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
     __THROWNL __nonnull ((1));

2、读写锁(read-write locks)

 

描述:一个或者多个读任务可以并发获取读者锁,而用于写的锁最多只能被一个写任务所持有。==感觉是为了优化屏障而生,不确定==
使用范围:仅__USE_UNIX98 或 defined __USE_XOPEN2K8 可用。

 

#include <pthread.h>

extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
                const pthread_rwlockattr_t *__restrict
                __attr) __THROW __nonnull ((1));

/* Destroy read-write lock RWLOCK.  */
extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock)
     __THROW __nonnull ((1));

/* Acquire read lock for RWLOCK.  */
extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock)
     __THROWNL __nonnull ((1));

/* Acquire write lock for RWLOCK.  */
extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
     __THROWNL __nonnull ((1));

/* Unlock RWLOCK.  */
extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)
     __THROWNL __nonnull ((1));


3、条件变量 (conditional variables)

描        述:主要用来等待某个条件的发生。可以用来同步同一进程中的各个线程。
使用范围:

#include <pthread.h>

extern int pthread_cond_init (pthread_cond_t *__restrict __cond,
                  const pthread_condattr_t *__restrict __cond_attr)
     __THROW __nonnull ((1));

/* Destroy condition variable COND.  */
extern int pthread_cond_destroy (pthread_cond_t *__cond)
     __THROW __nonnull ((1));

/* Wake up one thread waiting for condition variable COND.  */
extern int pthread_cond_signal (pthread_cond_t *__cond)
     __THROWNL __nonnull ((1));

/* Wake up all threads waiting for condition variables COND.  */
extern int pthread_cond_broadcast (pthread_cond_t *__cond)
     __THROWNL __nonnull ((1));

extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
                  pthread_mutex_t *__restrict __mutex)

extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
                   pthread_mutex_t *__restrict __mutex,
                   const struct timespec *__restrict __abstime)


4、自旋锁(spinlocks)


描述:当锁被某个线程占用时,其他线程在获取锁时会一直进行“忙循环-旋转-等待锁”。
使用范围:自旋锁不会休眠,故仅用于保护短的代码段。
API:

#include <pthread.h>

/* Initialize the spinlock LOCK.  If PSHARED is nonzero the spinlock can
   be shared between different processes.  */
extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)
     __THROW __nonnull ((1));

/* Destroy the spinlock LOCK.  */
extern int pthread_spin_destroy (pthread_spinlock_t *__lock)
     __THROW __nonnull ((1));

/* Wait until spinlock LOCK is retrieved.  */
extern int pthread_spin_lock (pthread_spinlock_t *__lock)
     __THROWNL __nonnull ((1));

/* Try to lock spinlock LOCK.  */
extern int pthread_spin_trylock (pthread_spinlock_t *__lock)
     __THROWNL __nonnull ((1));

/* Release spinlock LOCK.  */
extern int pthread_spin_unlock (pthread_spinlock_t *__lock)
     __THROWNL __nonnull ((1));

 

二、C语言提供的进程间同步机制


1、信号量(semaphore)

描       述:Linux中的信号量是一种睡眠锁。如果有一个任务企图获取一个不可用(被占用)的信号量时,信号量会被推进一个等待队列,然后让其休眠。
                  当持有的信号量可用(被释放)后,处于等待队列的那个任务才被唤醒,并获得该信号量。
使用范围:由于等待信号量线程会休眠(开销大),所以信号量适用于锁被长时间持有的情况。使用信号量的同时不能占用自旋锁(不允许休眠),否则不能进入休眠。
API:

 #include <semaphore.h>

extern int sem_init (sem_t *__sem, int __pshared, unsigned int __value)
     __THROW;
/* Free resources associated with semaphore object SEM.  */
extern int sem_destroy (sem_t *__sem) __THROW;

/* Open a named semaphore NAME with open flags OFLAG.  */
extern sem_t *sem_open (const char *__name, int __oflag, ...) __THROW;

/* Close descriptor for named semaphore SEM.  */
extern int sem_close (sem_t *__sem) __THROW;

/* Remove named semaphore NAME.  */
extern int sem_unlink (const char *__name) __THROW;

/* Wait for SEM being posted.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int sem_wait (sem_t *__sem);

/* Post SEM.  */
extern int sem_post (sem_t *__sem) __THROWNL;

2、信号SIGNAL


描        述:信号是一种比较始的通信机制。尽管提供的选项较少,但是它们非常有用。
使用范围:小数据。通常用于捕获系统定义的信号。

#include <signal.h>

/* Change the set of blocked signals to SET,
   wait until a signal arrives, and restore the set of blocked signals.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int sigsuspend (const sigset_t *__set) __nonnull ((1));

/* Get and/or set the action for signal SIG.  */
extern int sigaction (int __sig, const struct sigaction *__restrict __act,
              struct sigaction *__restrict __oact) __THROW;

extern __sighandler_t signal (int __sig, __sighandler_t __handler)
     __THROW;


3、System V

4、消息队列


描       述:产生消息并将其写到队列的进程通常称之为发送者,而一个或多个其他进程(逻辑上称之为接收者)则从队列获取信息。
使用范围:小数据量。

 

// #include <sys/msg.h>
/* Message queue control operation.  */
extern int msgctl (int __msqid, int __cmd, struct msqid_ds *__buf) __THROW;

/* Get messages queue.  */
extern int msgget (key_t __key, int __msgflg) __THROW;

/* Receive message from message queue.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t msgrcv (int __msqid, void *__msgp, size_t __msgsz,
               long int __msgtyp, int __msgflg);

/* Send message to message queue.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int msgsnd (int __msqid, const void *__msgp, size_t __msgsz,
           int __msgflg);


5、共享内存


描       述:一个进程向共享内存写入数据,共享这个内存区域的所有进程就可以立即看到其中的内容。
使用范围:大数据通信。使用共享内存需要注意的是多进程之间对一个给定存储区访问的互斥,若一个进程正在向共享区写数据,则在它操作完成之前,其他的进程不应当去读、写这些数据。

// include <sys/shm.h>
/* Shared memory control operation.  */
extern int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf) __THROW;

/* Get shared memory segment.  */
extern int shmget (key_t __key, size_t __size, int __shmflg) __THROW;

/* Attach shared memory segment.  */
extern void *shmat (int __shmid, const void *__shmaddr, int __shmflg)
     __THROW;

/* Detach shared memory segment.  */
extern int shmdt (const void *__shmaddr) __THROW;


6、管道和套接字

描       述:管道是用于交换数据的连接。一个进程向管道的一端供给数据,另一个在管道另一端取出数据,供进一步处理。几个进程可以通过一系列管道连接起来。
                  套接字不同于管道,套接字可以双向使用,还可以用于与通过网络连接的远程系统通信。

使用范围:常用于网络、大数据通信。

//#include <unistd.h>
/* Create a one-way communication channel (pipe).
   If successful, two file descriptors are stored in PIPEDES;
   bytes written on PIPEDES[1] can be read from PIPEDES[0].
   Returns 0 if successful, -1 if not.  */
extern int pipe (int __pipedes[2]) __THROW __wur;
/* Close the file descriptor FD.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int close (int __fd);

/* Read NBYTES into BUF from FD.  Return the
   number read, -1 for errors or 0 for EOF.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t read (int __fd, void *__buf, size_t __nbytes) __wur;

/* Write N bytes of BUF to FD.  Return the number written, or -1.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur;

//#include <sys/socket.h>
/* Create a new socket of type TYPE in domain DOMAIN, using
   protocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.
   Returns a file descriptor for the new socket, or -1 for errors.  */
extern int socket (int __domain, int __type, int __protocol) __THROW;

/* Put the local address of FD into *ADDR and its length in *LEN.  */
extern int getsockname (int __fd, __SOCKADDR_ARG __addr,
            socklen_t *__restrict __len) __THROW;

/* Open a connection on socket FD to peer at ADDR (which LEN bytes long).
   For connectionless socket types, just set the default address to send to
   and the only address from which to accept transmissions.
   Return 0 on success, -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);

/* Send N bytes of BUF to socket FD.  Returns the number sent or -1.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t send (int __fd, const void *__buf, size_t __n, int __flags);

/* Read N bytes into BUF from socket FD.
   Returns the number read or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t recv (int __fd, void *__buf, size_t __n, int __flags);

/* Send N bytes of BUF on socket FD to peer at address ADDR (which is
   ADDR_LEN bytes long).  Returns the number sent, or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t sendto (int __fd, const void *__buf, size_t __n,
               int __flags, __CONST_SOCKADDR_ARG __addr,
               socklen_t __addr_len);

/* Read N bytes into BUF through socket FD.
   If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address of
   the sender, and store the actual size of the address in *ADDR_LEN.
   Returns the number of bytes read or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n,
             int __flags, __SOCKADDR_ARG __addr,
             socklen_t *__restrict __addr_len);


/* Send a message described MESSAGE on socket FD.
   Returns the number of bytes sent, or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t sendmsg (int __fd, const struct msghdr *__message,
            int __flags);
/* Prepare to accept connections on socket FD.
   N connection requests will be queued before further requests are refused.
   Returns 0 on success, -1 for errors.  */
extern int listen (int __fd, int __n) __THROW;

/* Await a connection on socket FD.
   When a connection arrives, open a new socket to communicate with it,
   set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting
   peer and *ADDR_LEN to the address's actual length, and return the
   new socket's descriptor, or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int accept (int __fd, __SOCKADDR_ARG __addr,
           socklen_t *__restrict __addr_len);

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言提供的线程/进程间同步(锁)机制 的相关文章

  • python画函数图像-python实现画出e指数函数的图像

    这里用Python逼近函数y 61 exp x 同样使用泰勒函数去逼近 exp x 61 1 43 x 43 x 2 2 43 43 x n n 43 usr bin python coding utf 8 import numpy as
  • python使用方法视频-使用Python进行视频处理

    Imageio逐帧视频处理 安装 conda install imageio 将视频转换成图片 import imageio timeF 61 10 reader 61 imageio get reader 39 imageio cocka
  • python认证证书有哪些-python考试认证

    广告关闭 腾讯云双11爆品提前享 xff0c 精选热门产品助力上云 xff0c 云服务器首年88元起 xff0c 买的越多返的越多 xff0c 最高满返5000元 xff01 除了之前热议的加入高考和中小学教育之外 xff0c 现在连普通大
  • python代码写完怎么运行-Python 项目代码写完了,然后怎么打包和发布?

    你把你的代码写完了 xff0c 是不是要给别人使用下 xff0c 怎么打包你的项目代码呢 喂 xff0c 开源么 接下来小帅b就跟你说说 xff0c 如何打包你的代码 就拿我们上次演示的 用 Python 开发一个 个人计划 todolis
  • Zoom to Learn, Learn to Zoom

    Abstract 本文表明 xff0c 将机器学习应用于数字变焦时 xff0c 对真实 原始的传感器数据进行操作是有益的 现有的基于学习的超分辨率方法不使用真实的传感器数据 xff0c 而是对经过处理的RGB图像进行操作 我们表明 xff0
  • 6个非常实用的 Python 代码块,适合收藏~

    大家好 xff0c 今天分享几个平时我会用到的 Python 代码块 xff0c 每个都小而精 xff0c 喜欢记得关注 点赞 收藏 1 xff0c 批量修改文件名 日常工作中 xff0c 可能会有这样的需求 xff1a 把一个文件夹下所有
  • 1.音视频播放原理介绍

    音视频技术主要包含以下几种 xff1a 封装技术 xff0c 视频压缩技术 xff0c 音频压缩技术 xff0c 流媒体协议技术以及防盗链技术 接下来的几篇文章将对这几种技术做深入的研究和实践 下面简单说明一下视频播放的原理 xff08 以
  • 码云仓库建库

    方法一 xff1a 先将在码云上新建的仓库clone到本地 xff0c 修改后再push到码云仓库 git clone https gitee com 用户个性地址 工程名字 git 将远程仓库克隆到本地 在克隆过程中 xff0c 如果仓库
  • Python 画多图 统计直方图

    画直方图的命令是这个 xff1a 把里面的内容改了就可以 ec参数调整的是edgecolor xff0c 即框线颜色 matplotlib pyplot hist span class token punctuation span x sp
  • 输入2个整数,求最大公约数和最小公倍数

    输入2个整数 xff0c 求最大公约数和最小公倍数 关于最大公约数的算法 xff0c 古希腊数学家欧几里得已经在2200年前给出我们算法公式 xff0c 我们直接拿来用就可以了 欧几里得算法也被称为辗转相除法 xff0c 用来求最大公约数
  • WSL2 安装 图形系统 及遇到的坑

    wsl本身不带有图形界面 xff0c 需要自己安装 安装流程如下 xff1a 一 windows环境安装VcXsrv 默认安装即可 二 Ubuntu环境安装 xfce4 sudo apt get install xfce4 三 Ubuntu
  • 【美团】项目学习1:登录逻辑实现

    rest framework 和app应用 INSTALLED APPS span class token operator span span class token punctuation span span class token s
  • KMP算法

    一 何谓模式串匹配 模式串匹配 xff0c 就是给定一个需要处理的文本串 xff08 理论上应该很长 xff09 和一个需要在文本串中搜索的模式串 xff08 理论上长度应该远小于文本串 xff09 xff0c 查询在该文本串中 xff0c
  • webApi不能使用put和delete请求的处理方式

    今天调试webApi接口的时候 xff0c 分别使用get post put delete方式都试一下 xff0c 发现get和post方式都能正常调用 xff0c 但是使用put和delete的时候就报错了 xff0c 如下图所示 xff
  • Git 中 6 个基本常用命令

    大家好啊 xff0c 我是大田 想更深刻了解 Git 常用命令 xff0c 先来看看原理图 xff1a 我们使用 Git 操作的核心步骤就是 xff1a 先add代码到git缓存 然后commit到git本地仓库 最后push到远程Gith
  • Ubutun 使用easy-rsa 自签证书

    sudo apt install easy rsa mkdir root cert easy rsa ln s usr share easy rsa easy rsa cd root cert easy rsa easyrsa init p
  • Ubuntu ARM环境安装

    基础环境 防火墙 jiangzz 64 ubuntu span class token function sudo span ufw status Status inactive jiangzz 64 ubuntu span class t
  • 关系代数练习

    设有三个关系 xff1a S S SNAME AGE SEX SC S C GRADE C C xff0c CNAME xff0c TEACHER 试用关系代数表达式表示下列查询语句 xff1a 1 检索LIU老师所授课程的课程号和课程名

随机推荐

  • 使用Opencv调用摄像头失败的解决办法

    这几天参考 OpenCV3编程入门 书中的 调用摄像头采集图像的代码进行编程 xff0c 可是代码照着书上的打完了 xff0c 进行编译的时候竟然报错了 xff0c 于是乎就在网上查找错误的解决办法 xff0c 一开始是以为自己的驱动没装好
  • java日记(一)理解代码片段

    最近跟着Berkeley的CS61B学java 跨专业小白一个学起来比较吃力 xff0c 还好有大佬带着 决定开个贴子整理一下 代码片段是 xff1a DO NOT MODIFY ANYTHING ABOVE THIS LINE span
  • IOS - ReplayKit2 获取影像方向+ReplayKit的坑

    插件对象 64 interface SampleHandler RPBroadcastSampleHandler 重写方法 void processSampleBuffer CMSampleBufferRef sampleBuffer wi
  • Sublime Text运行C和C++程序

    原文链接 xff1a Sublime Text运行C和C 43 43 程序 Sublime Text 是一款当下非常流行的文本编辑器 xff0c 其功能强大 xff08 提供有众多的插件 xff09 界面简洁 还支持跨平台使用 xff08
  • VTK——自定义三维裁剪Widget,恢复Widget(任意形状,圆形,矩形裁剪)vtkCustomPaintWidget

    裁剪图标可以通过键盘上下键切换 xff0c 裁剪模式可以通过键盘左右键切换 xff0c 裁剪区域的显示 xff0c 可以显示为Mask或者显示为Contour边界 xff0c 测试效果如下
  • iOS UITableViewCell高度自适应

    UITableViewCell高度自适应 iOS8之后 我们只需要设置这两句代码之后 xff0c 即可放心的往cell的控件里面加上内容 xff0c cell会根据内部所有控件的高度动态的计算自己的高度从而显示出来 tableView es
  • 记一次vncServer的离线安装经历

    记一次vncServer的离线安装经历 背景 xff1a 需要在一台服务器上面装Oracle xff0c 但是服务器并不能接触到 xff0c 所以只能在客户端进行远程ssh操作 首先根据我以往装Oracle的经验 xff0c 先把安装包这些
  • debian 修改桌面背景

    64 桌面背景 push 图片到对应目录替换 xff1a adb push 图片 usr share desktop base active theme wallpaper contents images 64 当前语言查看 cat etc
  • 【计算机图形学基础教程】MFC基本绘图函数2

    MFC基本绘图函数 绘图工具类 CGdiObject类 xff1a GDI绘图工具的基类CBitmap类 xff1a 封装了GDI画刷 xff0c 可以选作设备上下文的当前画刷 xff0c 用于填充图形的内部CFont类 xff1a 封装了
  • thrift安装及示例

    1 简介 Apache Thrift软件框架 xff08 用于可扩展的跨语言服务开发 xff09 将软件堆栈与代码生成引擎结合在一起 xff0c 它有自己的跨机器的通信框架 xff0c 并提供一套库 它是一个代码生成器 xff0c 按照它的
  • you-get库二开,带UI界面的下载器

    you get库二开 带UI界面的下载器 span class token comment coding utf 8 span span class token comment Form implementation generated f
  • 工厂方法模式【Python篇】

    前言 在 设计模式 一书中工厂模式提到了 xff1a 工厂方法模式 xff08 Factory Method xff09 抽象工厂模式 xff08 Abstract Factory xff09 但是在实际过程中还有一种工厂模式经常被使用 x
  • docker安装gitlab 教程详解

    文章目录 前言一 环境处理二 docker部署gitlab三 调整gitlab配置1 配置克隆项目时所需2 root所需 参考 前言 环境 xff1a 1 xff1a Linux dnsserver moa kdzl cn 3 10 0 6
  • 问题解决:consider to specify kernel configuration cache directory through OPENCV_OCL4DNN_CONFIG_PATH par

    在使用Openpose代码运行的时候 xff0c 提示 xff1a consider to specify kernel configuration cache directory through OPENCV OCL4DNN CONFIG
  • zabbix监控平台搭建,及监控华为S5735S系列交换机和2288hv5服务器

    提要 无监控不运维 xff01 告别 救火员 的运维 二次搭建zabbix了 xff0c 这次打算以zabbix 集团基础硬件为主 43 prometheus k8s 43 微服务集群为主 43 grafana dashbroad展示 xf
  • Selenium 常用API大全(一篇就够)

    Selenium Crawl API xff08 一篇就够 xff09 万字长文整理不易 xff0c 希望对各位有所帮助 xff0c 欢迎大家一键三连 xff0c 点赞收藏加关注 同时也欢迎大家交流分享 xff0c 共同学习互相进步 xff
  • CV和NLP的区别

    本质 xff08 根 xff09 上没有区别 xff0c 都是信息信号处理 xff0c 都是高维信号的分解和组合 xff0c 但是信号的结构特征有区别 xff0c 所以需要不同的策略来挖掘数据信息 xff0c 即使用不同的分解和组合策略 x
  • 【Linux学习笔记】Linux环境搭建Maven私服

    Linux环境搭建Maven私服 一 概要说明二 搭建Nexus3 X xff08 3 18 xff09 2 1 下载Nexus2 2 解压Nexus2 3 启动Nexus2 3 1 创建一个nis用户来启动nexus2 3 2 修改nex
  • Win10喇叭图标出现红叉提示"未安装任何音频输出设备"

    如果你按网上搜的各种方法都试了还是没有声音 xff0c 那么就 1 关机 xff1b 2 拔掉所有的线 xff0c 包括电源线 xff1b 3 长按开机键 15s 重复三次 4 插上电源 xff0c 开机 xff08 此方法适用于我的笔记本
  • C语言提供的线程/进程间同步(锁)机制

    目录 一 C语言提供的线程间同步机制 1 互斥体 xff08 Mutex xff09 2 读写锁 xff08 read write locks xff09 3 条件变量 xff08 conditional variables xff09 4