首页 > 其他分享 >POSIX信号量

POSIX信号量

时间:2023-10-12 11:26:28浏览次数:32  
标签:core 信号量 POSIX 信号 printf 终止 yes include

背景介绍

多进程之间的同步机制:信号量。而在多线程编程中,通常更常见的是使用线程之间的同步机制,例如互斥锁、条件变量、信号量等,来实现线程之间的协调和通信。这些机制更适合用于线程级别的同步和通信需求。

POSIX信号

信号(signal)就是告知某一进程发生了某个事件的通知,有时也称为软件中断(software interrupt)。
信号通常是 异步 发生的,也就是说:进程预先不知道信号的准确发生时刻。

信号发送方式:

1)由一个进程发送给另一个进程(或自身)

2)由内核发送给某个进程

一般来说某一个进程需要定义一个信号回调函数用来等待一个特定信号的到来,只要有特定信号发生,信号处理函数就会被调用。一个signal()只能针对某一信号的处理,若要处理多个信号就要注册多个signal()
每一个信号都有一个名字,这些名字都是以SIG开头,且信号名被定义为正整数常量。不同的操作系统所能支持的信号数量都有不同。

在某个信号出现时,可以告诉内核按下列3种方式之一进行处理,我们称之为信号的处理或与信号相关的动作。

1)忽略此信号。大多数信号都可以使用这种方式进行处理,但 SIGKILLSIGSTOP 不能被忽略。

2)捕捉信号。SIGKILLSIGSTOP 不能被捕捉

3)执行系统默认动作。对于大多数信号的系统默认动作时终止进程。

信号表:

名字 说明 Linux 3.2.0 默认动作
SIGABRT 异常终止(abort) yes 终止+core
SIGALRM 定时器超时(alarm) yes 终止
SIGBUS 硬件故障 yes 终止+core
SIGCHLD 子进程状态改变 yes 忽略
SIGCONT 使暂停进程继续 yes 继续/忽略
SIGEMT 硬件故障 yes 终止+core
SIGFPE 算术异常 yes 终止+core
SIGHUP 连接断开 yes 终止
SIGILL 非法硬件指令 yes 终止+core
SIGINT 终端中断符 yes 终止
SIGIO 异步I/O yes 终止/忽略
SIGIOT 硬件故障 yes 终止+core
SIGKILL 终止 yes 终止
SIGPIPE 写至无读进程的管道 yes 终止
SIGPOLL 可轮询事件(poll) yes 终止
SIGPROF 梗概事件超时(setitimer) yes 终止
SIGPWR 电源失效/重启动 yes 终止+core
SIGQUIT 终端退出符 yes 终止+core
SIGSEGV 无效内存引用 yes 终止+core
SIGSTKFLT 协处理器栈故障 yes 终止
SIGSTOP 停止 yes 停止进程
SIGSYS 无效系统调用 yes 终止+core
SIGTERM 终止 yes 终止
SIGTRAP 硬件故障 yes 终止+core
SIGTSTP 终端停止符 yes 停止进程
SIGTTIN 后台读控制 tty yes 停止进程
SIGTTOU 后台写向控制 tty yes 停止进程
SIGURG 紧急情况(套接字) yes 忽略
SIGUSR1 用户定义信号 yes 终止
SIGUSR2 用户定义信号 yes 终止
SIGVTALRM 虚拟事件闹钟(setitimer) yes 终止
SIGWINCH 终端窗口大小改变 yes 忽略
SIGXPU 超过CPU限制(setrlimit) yes 终止或终止+core
SIGXFSZ 超过文件长度限制(setrlimit) yes 终止或终止+core

signal()

/* 包含的头文件 */
#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler); // 若出错,返回SIG_ERR

kill进程发送信号

测试SIGUSR1、SIGUSR2、SIGINT信号的捕获:
sig_usr.c

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <signal.h>

static void sig_usr(int signo)
{
	if (signo == SIGUSR1)
		printf("received SIGUSR1\n");
	else if (signo == SIGUSR2)
		printf("received SIGUSR2\n");
	else if (signo == SIGINT)
		printf("received SIGINT\n");
	else
		printf("received signal %d\n", signo);
}

int main(void)
{
	if (signal(SIGUSR1, sig_usr) == SIG_ERR)
	{
		printf("can't catch SIGUSR1\n");
	}
	if (signal(SIGUSR2, sig_usr) == SIG_ERR)
	{
		printf("can't catch SIGUSR2\n");
	}
	if (signal(SIGINT, sig_usr) == SIG_ERR)
	{
		printf("can't catch SIGINT\n");
	}
	while (true)
	{
		pause();
	}

	exit(0);
}

子进程结束发送信号

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>

static int g_running = 0;

static int handle(void)
{
    int second = 5;
    printf("sleep 5s");
    while (second--)
    {
        printf(".");
        fflush(stdout);
        sleep(1);
    }
    printf("\n");
    return 0;
}

static void sig_handler(int signo)
{
	pid_t pid;
    while (1)
    {
        pid = waitpid(-1, NULL, WNOHANG);
        if (pid > 0)
        {
            printf("child %d terminated\n", pid);
            g_running = 0;
        }
        if (pid == -1 || pid == 0)
        {
            break;
        }
    }
}

int main(void)
{
    g_running = 1;
    if (signal(SIGCHLD, sig_handler) == SIG_ERR)
	{
		printf("can't catch SIGCHLD\n");
        exit(1);
	}

    int pid = 0;
    pid = fork();
    if (pid < 0)
    {
        printf("fork error\n");
        exit(1);
    }
    else if (pid == 0)
    {
        handle();
        exit(1);
    }
    while (g_running)
    {
        pause();
    }
    pid_t pidMain;
    pidMain = getpid();
    printf("main %d exit\n", pidMain);
    exit(0);
}

标签:core,信号量,POSIX,信号,printf,终止,yes,include
From: https://www.cnblogs.com/caojun97/p/17753861.html

相关文章

  • POSIX 详解
    目录编写跨平台应用需要考虑的问题POSIX是什么,为什么需要POSIXPOSIX线程常用API介绍1、POSIX线程库2、创建线程pthread_create3、pthread_self4、线程等待pthread_join(主线程等待新线程)线程终止的方案pthread_exit函数pthread_cancel函数线程分离pthread_detach函数pthread中的线......
  • Linux内核信号量(semaphore)使用与源码分析
    https://blog.csdn.net/Auris/article/details/107404962一.在Linux内核驱动中使用信号量(semaphore)常规操作步骤:[0].定义信号量结构体变量;structsemaphoresem; [1].初始化信号量变量 voidsema_init(structsemaphore*sem,intn); eg.sema_ini......
  • 20_信号量
    信号量信号量&互斥量:创建、获取、释放、删除信号量用于同步,任务间或者任务和中断间同步;互斥量用于互锁,用于保护同时只能有一个任务访问的资源,为资源上一把锁。二值信号量:同步计数信号量:资源使用统计互斥量:互斥信号量其实就是一个拥有优先级继承的二值信号量递归互......
  • 深入了解信号量:多线程同步的得力工具
    随着计算机科学和软件工程的不断发展,多线程编程变得越来越重要。多线程允许程序同时执行多个任务,提高了程序的效率和性能。然而,多线程编程也引入了新的问题,例如竞态条件和数据竞争。为了解决这些问题,同步工具变得至关重要,而信号量是其中一个强大的工具。什么是信号量?信号量是一......
  • 4- 信号量& 互斥量
    信号量,计数值问题: 还是那个AB任务互斥调度的问题,B等A执行完毕的过程中,判断标志位会耗费CPU资源利用信号量,当没有信号的时候,不参与调度计数信号量(不能用来传输数据)staticSemaphoreData_txSemCalc;Xsemcalc=xSemaphoreCreateCounting(10,0);//最大值,初始值 计算完成后信......
  • C# 信号量 Semaphore
    ///<summary>///信号量,类似于占坑机制,初始设为5个空的坑位,且最大5个位置///</summary>staticreadonlySemaphoresemaphore=newSemaphore(5,5);staticvoidTest(){Task.Run(AAA);BBB();......
  • 初探信号量机制
    什么是信号量机制1965年,荷兰学者EdsgerDijkstra提出了一种经典的实现进程互斥、同步的方法--信号量机制。信号量机制用于解决并发访问共享资源的同步问题。信号量机制的主要目的是确保多个进程在共享资源时不会发生冲突,并且能够正确地同步和通信。信号量机制如今在操作系统......
  • chatGPT的js信号量实现
    信号量类在JavaScript中,可以使用Promise和async/await来模拟信号量,下面是一个简单的信号量实现:classSemaphore{constructor(maxConcurrency){this.maxConcurrency=maxConcurrency;this.currentConcurrency=0;this.queue=[];}asyncacqu......
  • 锁、递归锁、条件变量、信号量代码解析(Lock, RLock, Condition, Semaphore)
    锁Lock>>>help(type(threading.Lock()))Helponclasslockinmodule_thread:classlock(builtins.object)锁对象是一个同步原语。Alockobjectisasynchronizationprimitive.Tocreatealock,callthreading.Lock().Methodsare:acqui......
  • pandoc: pdflatex: createProcess: posix_spawnp: illegal operation
    RuntimeError:Pandocdiedwithexitcode"1"duringconversion:pandoc:pdflatex:createProcess:posix_spawnp:illegaloperation(Inappropriateioctlfordevice)报错原因这个报错原因可能是由于Pandoc在进行转换时尝试调用pdflatex命令时出错。在某些PDF转换过......