Desarrollo multiplataforma (Linux) basado en VS2019 C++ (1.4.2) - con señales de parámetros

Continuando con el artículo anterior, este capítulo primero aprenderá sobre señales con parámetros y funciones como sigqueue y sigaction.

Desarrollo multiplataforma (Linux) basado en VS2019 C++ (1.4) - Signal

I. Introducción

La función de eliminación que mencionamos en el último artículo envía una señal solo para un determinado proceso y no refleja los parámetros. También se mencionó anteriormente que no se puede compartir datos en el proceso, incluso si se define y modifica una variable global entre procesos secundarios, el proceso principal no sabe si se ha modificado o no. Entonces, esta situación requiere comunicación IPC para resolver, y kill no puede transmitir datos, entonces necesita usar una señal con parámetros

2. Prototipo de función

1. función de biblioteca sigaction - señal de enlace

Función: Se utiliza para cambiar el comportamiento de un proceso después de recibir una señal específica.

Archivo de encabezado <señal.h>

原型: int sigaction(int signum,const struct sigac tion *act,const struct sigaction *antiguo);

parámetro

  • El primer parámetro es el valor de la señal, que puede ser cualquier señal válida específica excepto sigkill y sigstop (defina su propia función de procesamiento para estas dos señales, lo que resultará en un error de instalación de la señal)
  • El segundo parámetro es un puntero a una instancia de la estructura sigaction.En la instancia de la estructura sigaction, se especifica el procesamiento de una señal específica.Puede estar vacío, y el proceso procesará la señal por defecto.
  • El objeto al que apunta el tercer parámetro oldact se usa para guardar el procesamiento original de la señal correspondiente, generalmente nulo .

Nota: Los parámetros dos y tres son punteros a estructuras. El segundo parámetro es el más importante.La función de procesamiento de señal está incluida en esta estructura, pero la función no se puede asignar directamente al segundo parámetro cuando se usa.

Valor devuelto: la función devuelve 0 en caso de éxito, -1 en caso de error

Vea la función sigaction en Linux de la siguiente manera

La estructura del correspondiente segundo parámetro sigaction es la siguiente

        No puede haber una función en la estructura c, pero aquí solo se reserva el puntero de función, y no rompe la estipulación de que no puede haber una función en la estructura. Para la estructura, es solo una variable de puntero (más especial, apuntando a una función)

        El primero es similar al puntero de función sin parámetros mencionado anteriormente, por lo que usamos la segunda función para implementar la señal con parámetros y luego usamos sa_flags para determinar si tiene parámetros.

2, función de biblioteca sigqueue-señal de envío

Función: La nueva llamada al sistema para enviar señales, principalmente para señales en tiempo real, admite señales con parámetros y se usa en pares con la función sigaction().

Ejemplo: int sigqueue(pid_t pid, int sig, const union sigval value);

parámetro  

  • El primer parámetro es la identificación del proceso que especifica la señal de recepción
  • El segundo parámetro determina la señal que se va a enviar
  • El tercer parámetro es una estructura de datos de unión union sigval (similar a la estructura, rara vez utilizada), que especifica los parámetros que pasa la señal, es decir, el llamado valor de 4 bytes.

Valor de retorno: 0 para éxito, -1 para falla

Vea la función sigqueue en Linux de la siguiente manera 

La unión sigval correspondiente del segundo parámetro es la siguiente 

 Donde sigval_int es el dato entero a enviar

3. Realización

1. Código de muestra

Este ejemplo implementa el proceso principal para enviar señales y pasar datos al proceso secundario

①La función de señal nula anterior (int i) solo es adecuada para el uso de señales sin parámetros, por lo que la función redefinida es la siguiente

void sigaction_func(int num, siginfo_t* info, void* vo)

El primer número de parámetro es el código de la señal recibida, y los datos recibidos se almacenan en la información del segundo parámetro.

② Los datos enviados por sigqueue deben ser en forma de consorcio

#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include<iostream>
#include <signal.h>
#include<stdio.h>
#include <stdlib.h>
using namespace std;

//带参数的信号
void sigaction_func(int num, siginfo_t* info, void* vo);
int main(){
    int pid = 0;
	//准备结构体
	struct sigaction  act;
	act.sa_sigaction = sigaction_func;
	act.sa_flags = SA_SIGINFO;//带参数的信号
	//绑定信号
	sigaction(SIGUSR1,&act,NULL);  //发送是sigqueue
	
	pid = fork();

	if (pid == 0)
	{
		while (true)
		{
			cout << "子进程运行中 ...pid =" << getpid() << endl;
			sleep(1);
		}
	}
	else if (pid > 0)
	{
		sleep(2);
		//准备要传递的数据
		union sigval value;
		value.sival_int = 111;
		//带参数发送信号
		sigqueue(pid, SIGUSR1, value);//第三个参数跟之前不一样,是一个联合体
		//卡住父进程
		while (1) {}
	}

	return 0;
}

void sigaction_func(int num, siginfo_t* info, void* vo)
{
	int x = info->si_int;
	cout <<"当前进程pid = "<<getpid()<<"  sigaction_func函数被调用了,num =  " << num << "  信号传递过来的数据是 x =  " << x<< endl;
}

2. Ejecución de resultados

4. Resumen

Los datos pasados ​​en el ejemplo anterior son solo un número entero, por lo que algunas personas pueden notar el segundo parámetro void * en la unión sigval (como se muestra a continuación), pensando que se puede usar para implementar otros tipos de datos, pero este no es el caso.

1. Cuando los primeros desarrolladores desarrollaron señales, solo admitían la transferencia de datos de tipo int, por lo que pensaron en reservar un void * para su uso posterior, pero desafortunadamente, la transferencia de datos de void * aún no se admite en la versión ubuntu20, y aún no se ha llevado a cabo Actualización, por lo que no se pueden pasar datos complejos (matrices, estructuras), lo cual es de muy mal gusto.

2. Debido a que IPC tiene cinco métodos de comunicación, no solo es posible usar señales para transferir datos entre procesos, ya que la operación problemática de las señales hace que sea solo el uso básico de la comunicación.

3. Cuando el proceso secundario recibe una señal desconocida (por ejemplo, cambie SIGUSR1 en el código anterior a SIGUSR2 en sigqueue(pid, SIGUSR1, value);) y la función de vinculación no se realiza, el resultado de ejecución es el siguiente, el el proceso hijo no sabe Haz nada y te quedarás atascado

Compilar de nuevo en linux

En este punto, verifique que el estado del proceso sea Z+ (estado zombi: el proceso secundario finaliza antes que el proceso principal. Hay un bucle infinito en el proceso secundario, que no debería terminar primero, sino porque el proceso secundario recibe una señal desconocida, se interrumpirá, el proceso hijo está atascado allí, es decir, lo original no funciona y no sabe qué hacer a continuación, entra en estado zombie, ocupa recursos y debe evitarse)

4. Cuando solo tengo un proceso, use kill para enviarle una señal en Linux

 El proceso recibe una señal desconocida (señal No. 10), imprime la señal 1 definida por el usuario, verifica el estado del proceso y descubre que no se puede encontrar el pid, es decir, se interrumpe y destruye, como si jugara el papel de matar el proceso (el anterior El proceso principal envía una señal desconocida al proceso secundario, pero simplemente se atasca). Entonces, para garantizar la ejecución normal del proceso, debe usar el blindaje de señal
 

Helicóptero a pequeña escala

 

Por favor, indique la fuente al cargar

Desarrollo multiplataforma (Linux) basado en VS2019 C++ (1.4.2) - con señales de parámetros

La máscara de señal de aprendizaje es la siguiente

https://blog.csdn.net/hml111666/article/details/123683046

Supongo que te gusta

Origin blog.csdn.net/hml111666/article/details/123564522
Recomendado
Clasificación