线程与进程(5)

news2024/11/23 12:16:55

目录

信号量(线程的同步 )

    信号量的分类:

    框架:

(1)信号量的定义(semaphore): 

(2)信号量的初始化:

(3)信号量的PV 操作

  (4)信号量的销毁

进程间的通信

通信方式分类:

管道

无名管道(pipe函数):

管道的读写规则:


信号量(线程的同步 )

  • 同步 ===》有 一定先后顺序的 对资源的排他性访问。
  • 互斥 ===》在多线程中对临界资源的排他性访问。

 linux下的线程同步  ===》信号量机制 ===》semaphore.h   posix sem_open();   

    信号量的分类:

  • 信号无名量 ==》线程间通信
  • 有名信号量 ==》进程间通信

    框架:

  1. 信号量的定义     sem_t  sem //造了一类资源 
  2. 信号量的初始化   sem_init 
  3. 信号量的PV操作  (核心) sem_wait()/ sem_post()
  4. 信号量的销毁。   sem_destroy

(1)信号量的定义(semaphore): 

      sem_t  sem;
信号量的类型信号量的变量
sem_t sem_w;
sem_t sem_r;

(2)信号量的初始化:

 int sem_init(sem_t *sem, int pshared, unsigned int value);

功能:将已经定义好的信号量赋值。
参数:sem 要初始化的信号量
           pshared = 0 ;表示线程间使用信号量;pshared!=0 ;表示进程间使用信号量
           value 信号量的初始值,一般无名信号量,都是二值信号量0 /1;0 表示红灯,进程暂停阻塞;
1 表示绿灯,进程可以通过执行
返回值:成功  0; 失败  -1;

sem_init(&sem_w, 0, 1);
sem_init(&sem_r, 0, 0);

(3)信号量的PV 操作

  • P ===》申请资源===》申请一个二值信号量 sem_wait();
  • V ===》释放资源===》释放一个二值信号量 sem_post();

    int sem_wait(sem_t *sem); //P操作 

功能:
          判断当前sem信号量是否有资源可用。
          如果sem有资源(==1),则申请该资源,程序继续运行
          如果sem没有资源(==0),则线程阻塞等待,一旦有资源
          则自动申请资源并继续运行程序。

          注意:sem 申请资源后会自动执行 sem = sem - 1;
参数:sem 要判断的信号量资源
返回值:成功 0 ;失败 -1

 int sem_post(sem_t *sem); //V操作

功能:
          函数可以将指定的sem信号量资源释放
          并默认执行,sem = sem+1;
          线程在该函数上不会阻塞。
参数:sem 要释放资源的信号量
返回值:成功 0
            失败 -1;

  (4)信号量的销毁

int sem_destroy(sem_t *sem);

功能:使用完毕将指定的信号量销毁
参数:sem要销毁的信号量
返回值:成功 0;失败  -1;

练习;用多线程程序设计一个火车票售票系统,

        要求:1. 至少有两个售票窗口,每个售票窗口
                2. 不能重复买票,将100张车票均匀的从两个窗口卖出即可。

#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
#include <semaphore.h>

#define handle_error_en(en, msg) \
    do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)

int ticket = 100;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#if 0
void *doWin1(void *arg)
{
	int i = 0;
	while (ticket)
	{
		pthread_mutex_lock(&mutex);
		ticket--;
		printf("win1 sell ticket = %d\n",100-ticket);
		pthread_mutex_unlock(&mutex);
	}

	pthread_exit(NULL);
}
#endif 
void *doWin1(void *arg)
{
	int i = 0;
	pthread_mutex_lock(&mutex);
	while (ticket)
	{
		ticket--;
		printf("win1 sell ticket = %d\n",100-ticket);
		pthread_mutex_unlock(&mutex);
	}

	pthread_exit(NULL);
}

void *doWin2(void *arg)
{
	int i = 0;
	pthread_mutex_lock(&mutex);
	while (ticket)
	{
		ticket--;
		printf("win2 sell ticket = %d\n",100-ticket);
		pthread_mutex_unlock(&mutex);
	}

	pthread_exit(NULL);
}


int main(int argc, const char *argv[])
{
	pthread_t tid[2];

	int ret = pthread_create(&tid[0],NULL,doWin1,NULL);
	if (ret != 0)
		handle_error_en(ret,"pthread_create fail");
	
	ret = pthread_create(&tid[1],NULL,doWin2,NULL);
	if (ret != 0)
		handle_error_en(ret,"pthread_create fail");


	pthread_join(tid[0],NULL);
	pthread_join(tid[1],NULL);
	
	return 0;
}

进程间的通信

通信方式分类:

(1)不同主机之间(基于内存)

        1)古老的通信方式:管道(无名管道、有名管道);信号;

        2)IPC对象通信(改进):【a:消息队列(用的相对少,这里不讨论)】;【b:共享内存//最高效】;【c:信号量集//信号量】;

(2)不同主机之间(socket 网络部分);

管道

  • 无名管道 ===》pipe ==》只能给有亲缘关系进程通信
  • 有名管道 ===》fifo ===》可以给任意单机进程通信(同一主机内)

特性:

  1. 管道是半双工的工作模式
  2. 所有的管道都是特殊的文件不支持定位操作。lseek->> fd  fseek ->>FILE* 数据流 --- FIFO(first in first out)
  3. 管道是特殊文件,读写使用文件IO。 fgets,fread,fgetc,open,read,write,close;;
无名管道(pipe函数):

特性:【亲缘关系进程使用】;【有固定的读写端】;

流程:

创建并打开管道: pipe函数

int pipe(int pipefd[2]);

功能:创建并打开一个无名管道

参数:

  • pipefd[0] ==>无名管道的固定读端//0 -- 标准输入, 
  • pipefd[1] ==>无名管道的固定写端//1 -- 标准输出 

 返回值:成功 0;失败 -1;

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int fd[2];

    if(pipe(fd) < 0)
    {
        perror("pipe fail");
        return -1;
    }

    printf("fd[0] = %d\n", fd[0]);
    printf("fd[1] = %d\n", fd[1]);

    char buf[] = "hello world";
    write(fd[1], buf, strlen(buf));

    char s[100] = {0};
    read(fd[0], s, sizeof(s));

    printf("s = %s\n", s);
    return 0;
}

注意:无名管道的架设应该在fork之前进行

管道的读写规则:
读端:pipefd[0]写端:pipefd[1]结果
存在存在写管道:管道空:可以写数据
               管道满:会造成-->写阻塞 
不存在存在写管道:系统会给进程发一个信号SIGPIPE(管道破裂)
存在存在读管道:管道空,读不到数据,这时会造成读操作阻塞
存在不存在读管道:如果管道中有数据,则读取这些数据;如果没有数据,读操作不阻塞,立即返回!

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2046237.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu Linux安装Go语言

Golang是Google公司在2007年开始开发的一种静态强类型、编译型语言。Go语言被设计成一门简单、高效且可靠的编程语言&#xff0c;旨在解决大规模网络服务和分布式系统开发中的复杂性问题。Go语言结合了动态语言的开发速度和C/C等编译型语言的性能与安全性&#xff0c;提供了强大…

[DL]深度学习_针对图像恢复的高效扩散模型DiffIR

DiffIR: Efficient Diffusion Model for Image Restoration Abstract 扩散模型(DM)通过将图像合成过程建模为去噪网络的顺序应用&#xff0c;实现了SOTA的性能。然而&#xff0c;与图像合成不同的是&#xff0c;图像恢复(IR)对生成符合ground-truth的结果有很强的约束。因此&am…

家穷就去互联网

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330#rd 《网安面试指南》http://mp.weixin.qq.com/s?…

AI编程工具合集(附使用地址)

在AI编程工具领域&#xff0c;随着技术的飞速发展&#xff0c;越来越多的工具正在改变编程的方式。以下是目前排名前十的AI编程工具合集&#xff0c;提供了丰富的功能来提升开发效率&#xff0c;并在多个编程场景中帮助开发者解决问题。 1. GitHub Copilot • 是什么: GitHub C…

打靶笔记--medium_socnet

medium_socnet 靶机地址:https://www.vulnhub.com/entry/boredhackerblog-social-network,454/ 内容简介&#xff1a; 这是本系列的第04次打靶&#xff0c;我选择了一个中等难度的靶机。在这次打靶过程中&#xff0c;我们将使用到以下攻击手段&#xff1a; 主机发现 端口扫…

javaEE WebServlet、SpringWebMVC、SpringBoot实现跨域访问的4种方式及优先级,nginx配置跨域

文章目录 1. 前置知识2. 原理和解决方案总结2.1. 跨域不通过原理流程图2.2. 实现原理&#xff1a;添加以下http响应头2.3. 四种跨域实现方式及优先级&#xff08;从高到低&#xff09; 3. 具体实现代码3.1. 跨域全局配置方式-Filter(全适用)3.2. 跨域全局配置方式-SpringMvc3.3…

鸿蒙内核源码分析(内存规则篇) | 内存管理到底在管什么

先说如果没有内存管理会怎样? 那就是个奴才们能把主子给活活踩死&#xff0c; 想想主奴不分&#xff0c;吃喝拉撒睡都在一起&#xff0c;称兄道弟的想干啥? 没规矩不成方圆嘛&#xff0c;这事业肯定搞不大&#xff0c;单片机时代就是这种情况. 裸机编程&#xff0c;指针可以…

【笔记】MSPM0G3507使用RT-Thread FinSH——MSPM0G3507与RT_Thread(四)

接上篇 KEIL 添加 FinSH 源码 添加自己的函数实现rt_hw_console_getchar 修改为&#xff1a; #include "C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\G3507_RTT\ti_msp_dl_config.h"//ti_msp_dl_config.h的绝对地址RT_WEAK char rt_hw_con…

Java知识点一——列表、表格与媒体元素

显示表格边框&#xff1a;<table border"1"></table> 因为初始的表格是没有边框的 collapse相邻的单元格共用同一条边框&#xff08;采用 collapsed-border 表格渲染模型&#xff09;。 separate默认值。每个单元格拥有独立的边框&#xff08;采用 sep…

Haskell爬虫中日志记录:监控HTTP请求与响应

在当今信息爆炸的时代&#xff0c;数据抓取成为了获取信息的重要手段。Haskell&#xff0c;以其强大的类型系统和函数式编程特性&#xff0c;成为了编写高效、可靠爬虫的理想选择。然而&#xff0c;随着爬虫的运行&#xff0c;监控其行为变得尤为重要。本文将探讨如何在Haskell…

ROS2从入门到精通2-4:Rviz2插件制作案例(以工具栏和多点导航插件为例)

目录 0 专栏介绍1 Rviz2插件2 项目配置3 案例一&#xff1a;工具栏插件4 案例二&#xff1a;多点导航插件5 综合演示5.1 添加插件5.2 多点巡航 0 专栏介绍 本专栏旨在通过对ROS2的系统学习&#xff0c;掌握ROS2底层基本分布式原理&#xff0c;并具有机器人建模和应用ROS2进行实…

企业图纸防泄密的最佳方案,10款好用的图纸加密软件排行榜

在数字化时代&#xff0c;企业的图纸文件往往包含了极其重要的知识产权和技术秘密&#xff0c;因此保护这些图纸的安全至关重要。有效的图纸加密不仅能防止未授权访问&#xff0c;还能确保图纸在内外部流转过程中的完整性与安全性。本文将介绍十款2024年市场上评价较高的图纸加…

基于Mysql的商业辅助决策系统的设计与实现

TOC springboot295基于Mysql的商业辅助决策系统的设计与实现 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人们…

零-STM32与嵌入式

目录 一、嵌入式概述 二、微控制器的关系 三、STM32的学习原因 四、STM32的应用领域 五、STM32的就业前景 六、STM32开发方式 (1) 寄存器开发&#xff08;自己做饭&#xff0c;自己吃&#xff09; (2) 函数库开发&#xff08;别人做饭&#xff0c;自己吃&#xff09; …

喜报 亚信安全再次入选湖北省网络安全应急技术支撑单位

近日&#xff0c;中共湖北省委网络安全和信息化委员会办公室和国家计算机网络应急技术处理协调中心湖北分中心公布了《关于开展第二届湖北省网络安全应急技术支撑单位评选工作的通知》&#xff0c;亚信安全凭优秀的产品技术实力和丰富的安全服务实践经验&#xff0c;连续两届成…

调研适合c++训练和部署的框架

目录 1. caffe 2. TensorFlow 3. Pytorch 4. PaddlePaddle 5. darknet 1. caffe GitHub - BVLC/caffe: Caffe: a fast open framework for deep learning. Caffe (Convolutional Architecture for Fast Feature Embedding) Caffe是一个早期流行的深度学习框架&#xff0…

GreptimeDB融资数百万美元; Oracle提供免费长期MySQL; 谷歌大模型支持云数据库问题洞察

重要更新 1. 开源时序数据库 GreptimeDB宣布完成数百万美元的新一轮融资。GreptimeDB是一款Rust 语言编写的时序数据库&#xff0c;具有分布式&#xff0c;开源&#xff0c;云原生&#xff0c;兼容性强等特点&#xff0c;帮助企业实时读写、处理和分析时序数据的同时&#xff0…

Linux设备驱动——模块的构造、运行与设计 与众不同的hello world与点灯

编写一个Linux下的设备驱动&#xff0c;首先要准备好对应内核版本的内核源码树文件。 该系列的全部文章都以嵌入式系统的ARM-Linux的环境进行阐述&#xff0c;并以交叉编译的方式在主机Ubuntu20.04系统上编译和ARM开发板上跑测 (E2000Q、H616、或者IMX6ULL看情况交叉着使用) 关…

MySQL基础练习题44-只出现一次的最大数字

目录 题目 情况一 准备数据 分析数据 情况二 准备数据 实现一 题目 单一数字 是在 MyNumbers 表中只出现一次的数字。 找出最大的 单一数字 。如果不存在 单一数字 &#xff0c;则返回 null 。 情况一 准备数据 ## 创建库 create database db; use db;## 创建表 Cre…

腾讯云短信正文模板每个变量取值最多支持6个字符出现的问题及应对方法

目录 一、参考链接二、应对方法 一、参考链接 对于长期未使用的账号及 2024 年 1 月 25 日后开通的新账号&#xff0c;腾讯云对短信正文模板的变量进行了限制&#xff1a; 验证码短信&#xff1a;每个变量取值最多支持6位纯数字。 非验证码短信&#xff1a;每个变量取值最多支…