信号量和信号

信号量和信号

初步理解信号量

1、信号量本质就是一个资源计数器,类似 int cnt = n;

2、用来描述临界资源的资源数量的多少

3、我们最怕的是什么?

答:多个执行流去共享访问同一个资源

什么是信号量

信号量的本质其实就是一个计数器
1、成功申请了资源计数器就是有了申请这个资源的权限

2、问:成功申请到了这个资源计数器,就是我们有了这个资源了吗?

答:并不是,只是我们可以去申请这个资源,但还并没有申请到

3、这个计数器可以有效的限制了执行流的数量

4、任何执行流要去访问临界资源都得先访问这个临时计数器资源

pv操作

在题目中很容易碰到有pv操作的题目,pv操作就是申请二态的信号量,也就是0 1 两态

申请信号量 -- p操作

释放信号量 ++ v操作

要么不申请,要么完成

没有正在申请的操作

结论

1、从两个角度去看,信号量的本质可以分为

①计数器资源,原子性,p v 操作

②对临界资源的预定机制

2、要想申请临界资源,先申请信号量资源

3、如果是 0 1 两态,就是二元信号量,具有互斥功能

信号

相关概念

1、一个进程,必须要有具备处理信号的能力,即使这个信号还没有出现,也要有能够处理的它的能力,信号的处理能力是进程的内置功能

2、一个进程接受到一个信号是可能并不会立即相应这个信号,而是等到合适的时机去相应

3、一个信号从出现到响应是会有一个时间间隔,所以进程必须要具备临时保存已经出现的信号的能力

前台进程与后台进程

一个bash只能由一个前台进程,可以有很多个后台进程。

一般我们运行的进程是前台进程,可以用组合键 ctrl c 进行结束它,有没有什么方法将我们运行的前台进程变成后台进程呢?
有的,兄弟包有的,只需要在我们的运行进程后边加上一个 & 就变成了后台进程,此时ctrl c就删不掉它了,删掉的方法就是kill -9 pid即可

cpp 复制代码
#include<iostream>
#include<unistd.h>
using namespace std;


int main()
{
    while(1)
    {
        cout<<"hello linux "<<getpid()<<"\n\t"<<endl;
        sleep(1);
    }

    return 0;
}

此时用ctrl c是删不掉它的,可以用另一个bash使用命令kill -9 pid删掉即可

信号的查看方式

kill -l查看即可

1-31\]是普通信号,\[34,36\]是实时信号 信号的处理方式: 1、默认 2、无视 3、自定义

信号的产生

1、组合键

比如 : ctrl+c ctrl+z ctrl+\

2、kill 命令

3、系统调用
一、signal函数

cpp 复制代码
#include <iostream>
#include <signal.h>
#include <unistd.h>
using namespace std;

void func(int signo)
{

    cout << "hello linux" << endl;
    exit(1);
}

int main()
{
    signal(SIGINT, func);
    while(true)
    {
        cout<<"hello world"<<endl;
        sleep(1);
    }

    return 0;
}

这里ctrl c成功杀死了进程,但是也成功打印了hellp linux.

因为有一些信号即使改变了它的功能它的原本功能也并不会改变。
2、kill

cpp 复制代码
#include <iostream>
#include <signal.h>
#include <unistd.h>
using namespace std;

void func()
{

    cout << "hello linux" << endl;
    exit(1);
}

int main(int argc,char* argv[])
{
    
    if(argc != 3)
    {
        func();
        exit(1);
    }
    int signum = stoi(argv[1]);
    pid_t pid = stoi(argv[2]);
    int n = kill(pid,signum);

    return 0;
}

可以通过我们自己的进程模拟kill指令
3、raise

cpp 复制代码
#include <iostream>
#include <signal.h>
#include <unistd.h>
using namespace std;

void func(int signo)
{

    cout << "hello linux" << endl;
    exit(1);
}

int main()
{
    //signal(SIGINT, func);
    int cnt = 5;
    while(true)
    {
        cout<<"hello world"<<endl;
        sleep(1);
        cnt--;
        if(cnt == 0)
        {
            raise(2);
        }
    }

    return 0;
}

程序运行5秒后自动停了下来
abort:给自发6号命令

cpp 复制代码
#include <iostream>
#include <signal.h>
#include <unistd.h>
using namespace std;

void func(int signo)
{

    cout << "hello linux" << endl;
    exit(1);
}

int main()
{
    //signal(SIGINT, func);
    int cnt = 5;
    while(true)
    {
        cout<<"hello world"<<endl;
        sleep(1);
        cnt--;
        if(cnt == 0)
        {
            //raise(2);
            abort();
        }
    }

    return 0;
}

5秒后自动删除进程!

相关推荐
多恩Stone1 小时前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
不是二师兄的八戒2 小时前
Linux服务器挂载OSS存储的完整实践指南
linux·运维·服务器
蜡笔小马2 小时前
21.Boost.Geometry disjoint、distance、envelope、equals、expand和for_each算法接口详解
c++·算法·boost
一个人旅程~2 小时前
如何用命令行把win10/win11设置为长期暂停更新?
linux·windows·经验分享·电脑
超级大福宝2 小时前
N皇后问题:经典回溯算法的一些分析
数据结构·c++·算法·leetcode
2302_799525743 小时前
PCI、PCIe 和 NVLink
linux
~远在太平洋~3 小时前
Linux 基础命令
linux·服务器·数据库
weiabc3 小时前
printf(“%lf“, ys) 和 cout << ys 输出的浮点数格式存在细微差异
数据结构·c++·算法
Gofarlic_oms13 小时前
避免Kisssoft高级分析模块过度采购的科学评估方法
大数据·linux·运维·人工智能·matlab