信号量和信号

信号量和信号

初步理解信号量

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秒后自动删除进程!

相关推荐
沫璃染墨10 分钟前
从零入门计算机网络系列(十一):HTTP协议进阶——从重定向原理到GET/POST与Fiddler抓包
linux·服务器·开发语言·网络·c++·tcp/ip·html
揽星河..2 小时前
【C语言】分支和循环
c语言·c++·算法
AI_Lab012 小时前
宝塔用了两年,有没有必要换成轻量方案?
linux·运维·服务器
by209992 小时前
Linux GDB 调试与 CGDB 使用
linux·运维·服务器·经验分享
星恒随风3 小时前
Linux网络编程:应用层协议究竟是什么?从网络计算器到TCP Socket抽象基类完整实现
linux·网络·笔记·tcp/ip
Fuyo_11193 小时前
C++ AVL树保姆级详解:从平衡因子到四大旋转机制
java·c++·算法
傲世仙尊4 小时前
继承-类设计层次复用切片转换与菱形继承的死结
c++
架构师伯子明4 小时前
FFmpeg C++学习(一):编译和demo
开发语言·c++·学习
纪念 2295 小时前
C++算法(六)
开发语言·c++·算法
ShineWinsu5 小时前
对于Qt:QCheckBox常见属性的详细解析
c++·qt·面试·笔试·gui·qcheckbox·多选框