首页 > 系统相关 >Linux线程-POSIX信号量与锁以及条件变量

Linux线程-POSIX信号量与锁以及条件变量

时间:2024-09-28 14:22:24浏览次数:3  
标签:函数 Linux 信号量 线程 pthread POSIX sem

POSIX信号量

POSIX没有元素这个概念相比于SYSTEM-V更简洁,POSIX不一定适用老版本;二者都是系统范畴,都需要手动删除,POSIX相关函数属于线程库,所有编译时需要末尾加上-lpthread选项

POSIX

  • POSIX有名信号量

    1. 主要用于进程间通信

    2. 创建成功后,器特殊文件存放路径:/dev/shm/

  • POSIX无名信号量(属于进程间,随着进程的消亡而消失)

    1. 主要用于线程间通信

//无名信号量用于线程间同步和互斥
#include "head.h"

sem_t data;
sem_t space;

void* routine(void* arg)
{
    char* num = (char*)arg;
    
    while(1)
    {
        sem_wait(&data);
        
        printf("routine: %s\n", num);
        
        sem_post(&space);
    }
}

int main()
{
    char str[100];
    
    // 第一个参数:创建成功后返回的信号量标识符
    // 第二参数:  0代表线程间通信
    // 第三个参数:当前信号量的初始值
    sem_init(&data, 0, 0);
    sem_init(&space, 0, 1);
    
    pthread_t tid;
    pthread_create(&tid, NULL, routine, str);
    
    while(1)
    {
        sem_wait(&space);
        
        bzero(str, sizeof(str));
        fgets(str, sizeof(str), stdin);
        
        sem_wait(&data);
    }
    
    return 0;
}

锁与条件变量

//用于验证互斥锁读写锁与条件变量(用于解决互斥锁的死锁问题)

// 定义一个共享资源,通过条件变量控制访问
int balance = 0;
// 条件变量通常需要结合互斥锁使用
pthread_mutex_t m;
// 条件变量是用于解决互斥锁使用过程中可能出现的死锁
pthread_cond_t v;

//线程函数 -- 相当于兄弟姐妹
void* routine(void* arg)
{
    //对共享资源访问时需要加锁、解锁操作
    pthread_mutex_lock(&m);
    
    while(balance < 100)
    {
        // 卡里没钱则进入条件等待队列,进入队列时,条件变量会自动执行解锁操作,这是条件变量底层已经封装好了,无需手动操作
        pthread_cond_wait( &v, &m);
    }
    
    fprintf(stderr, "[%lu]:取钱之前的金额:%d\n", pthread_self(), balance);
    balance -= 100;
    
    pthread_mutex_unlock(&m);
    
    pthread_exit(NULL);
}

// ./a.out 10
int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        printf("未输入线程数量\n");
        return -1;
    }
    
    // 1、初始化互斥锁和条件变量
    pthread_mutex_init(&m, NULL);
    pthread_cond_init(&v, NULL);
    
    // 2、创建线程
    pthread_t tid;
    int nThread_num = atoi(argv[1]);
    for(int i = 0; i < nThread_num; i++)
    {
        //创建多个兄弟姐妹
        pthread_create(&tid, NULL, routine, NULL);
    }
    
    // 3、让当前主线程给balance增值
    int i = nThread_num
    while(i--)
    {
        //对共享资源访问时需要加锁、解锁操作
        pthread_mutex_lock(&m);
        // 相当于家长汇钱
        balance += 100;
        // 向条件等待队列发送通知,汇钱后通知兄弟姐妹
        pthread_cond_broadcast(&v);
        
        pthread_mutex_unlock(&m);
        
        sleep(2);//为了便于查看条件等待队列的过程
    }
    //退出主线程
    pthread_exit(NULL);
    //退出进程
    //return 0;
}

可重入函数

一个函数如果同时被多个线程调用,返回的结果都是严格一致的,那么就是可重入函数,否则就是不可重入函数。

例如:排序函数是可重入函数,取地址函数是不可重入函数

多个线程调用同一可重入函数出现不同结果原因:

1、函数内部使用了共享资源,如全局变量

2、函数内部调用了其他不可重入函数

3、函数执行结果与硬件设备相关

标签:函数,Linux,信号量,线程,pthread,POSIX,sem
From: https://blog.csdn.net/LHB15173352347/article/details/142610435

相关文章

  • 解决安装windows后Linux引导被覆盖的问题
    强烈谴责windows的霸道行径!!!首先安装windows时提示检测到EFI分区为NTFS格式,请格式化为FAT32后重试。但是所有的EFI分区都是FAT32的。然后我尝试着把之前安装Linux时设置的EFI分区删了,使用windows安装程序自己生成的EFI分区,然后就安装成功了,但是Linux就进不去了。方法一:再安装一个......
  • Linux查看固态盘总写入量等信息
    sudoaptinstallgsmartcontrol然后smartctl命令就有了。先尝试直接打开gmartcontrol(通过终端或者启动器)结果发现看不了。这时可以使用smartctl命令查看。首先找到固态盘的设备名。在终端中输入ls/dev/nvm*第一个就是固态盘的设备名。然后输入sudosmartctl-a/dev/......
  • Linux挂载ext4 ramdisk
    划分一块DRAM作为ramdisk在/etc/default/grub改:GRUB_CMDLINE_LINUX="memmap=4G!4G"然后重启就可以看到/dev/pmem0,这就是划分出来的ramdisk了。格式化mkfs-text4/dev/pmem0挂载这里的挂载点设置为了/mnt/pmem。mkdir-p/mnt/pmemmount-text4/dev/pmem0/mnt/pmem......
  • Linux多线程复制目录
    比如有一个目录a需要复制:mkdiratoucha/amkdira/btoucha/b/ctreeaa├──a└──b└──c将其复制为目录d只需要用find找出目录下所有的文件,然后用gnu-parallel开多线程逐个复制即可:mkdirdcdafind.-typef|parallel-j4cp--parents{}../dtre......
  • 编译安装linux内核
    下载内核https://www.kernel.org/一般下载tarball,也就是.tar.xz格式的源码包。如果/够大,可以直接解压到/usr/src,也可以解压到机械盘上。配置.config里面是一些flag,内核编译的时候会读取这个文件,根据这些flag来配置。常用的有:CONFIG_LOCALVERSION附加在在内核的version......
  • 加速clone linux kernel
    tunagitclonehttps://mirrors.tuna.tsinghua.edu.cn/git/linux.gitgiteegitee.com有一个码云极速下载的用户,id是mirrors。这个用户维护了很多github的仓库的镜像,其中就有linuxkernel:[email protected]:mirrors/linux.git实测可以跑满带宽。建议不要用https的方式......
  • 使得两次编译linux内核产生一样的结果
    exportINSTALL_MOD_STRIP=-sexportKBUILD_BUILD_TIMESTAMP=0exportKBUILD_BUILD_USER=rootexportKBUILD_BUILD_HOST=localhostmakemrpropermakeallnoconfigmake-j4其中makeallnoconfig表示除必须的选项外,其它选项一律不选。然后就可以发现vmlinux和arch/x86/bo......
  • 解决linux下latex无法使用consolas的问题
    在网上找了好久都没有合适的解决方案TT。结合报错信息,发现其实/usr/local/texlive/2019中已经有inconsolata,但是编译时xelatex找的是/usr/share/texlive,里面有一些字体没有(我也不懂为什么官方要这样搞)。于是我们只需要把/usr/share下的相关文件夹替换成/usr/local/texlive/2019中......
  • 信号量的秘密:Python中的Semaphore详解
    引言随着计算机硬件的发展,多核处理器已经成为了标准配置。这使得开发人员可以利用并发编程技术来提高应用程序的性能。然而,在并发环境下,资源共享和访问控制成了一个棘手的问题。Semaphore(信号量)就是一种常用的解决此类问题的技术。通过限制对共享资源的同时访问数量,Semapho......
  • linux性能优化实践1
    理解应用程序和系统的少数几个基本原理,再进行大量的实战练习,建立起整体系统性能的全局观。你不需要了解每个组件的所有实现细节,只要能理解它们最基本的工作原理和协作方式。性能指标:应用负载的视角:高并发、响应快,影响产品终端用户体验系统资源的视角:资源使用率、饱和度性能问......