$ dormir 100 &[1] 9298
usar
pidofPuede ver el ID del proceso del nombre del programa especificado:
$ pidof dormir9298
$ gato /proc/9298/maps08048000-0804b000 r-xp 00000000 08:01 977399 /bin/sleep0804b000-0804c000 rw -p 00003000 08:01 977399 /bin/sleep0804c000-0806d000 rw-p 0804c000 00:00 0 [montón]b7c8b000-b7cca000 r--p 00000000 08:01 443354...bfbd8000-bfbed000 rw-p bfbd8000 00:00 0 [pila]ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]
Una vez ejecutado el programa, se carga en la memoria y se convierte en un proceso. Lo anterior muestra la imagen de la memoria (memoria virtual) del proceso, incluidas las instrucciones del programa, los datos y parte del espacio de pila utilizado para almacenar los parámetros de la línea de comando del programa y las variables de entorno. Se ha asignado el espacio de montón utilizado para la aplicación de memoria dinámica.
Para obtener detalles sobre el proceso de ejecución del programa en la línea de comando, consulte "El momento de ejecución del programa en la línea de comando de Linux".
De hecho, existen otras formas de crear un proceso, es decir, dejar que el programa se ejecute. Por ejemplo, a través de algunas configuraciones, puede iniciar automáticamente el programa cuando se inicia el sistema (para obtener más detalles, consulte.
hombre iniciado), o configurando
crondo(o
en) para permitirle iniciar el programa regularmente. Además, hay otra forma: escribir un script de Shell y escribir el programa en un archivo de script. Cuando se ejecuta el archivo de script, el programa en el archivo se ejecutará y se convertirá en un proceso. No se presentarán los detalles de estos métodos. Aprendamos cómo ver las propiedades del proceso.
Una cosa que debe agregarse es: para ejecutar el programa en la línea de comando, puede pasar
límiteLos comandos integrados se utilizan para configurar los recursos que un proceso puede utilizar, como la cantidad máxima de descriptores de archivos que un proceso puede abrir, el espacio máximo de pila, el espacio de memoria virtual, etc. Para un uso específico, consulte
ayuda.
puede pasar
PDUtilice el comando para ver los atributos y el estado relacionados con el proceso. Esta información incluye el usuario al que pertenece el proceso, el programa correspondiente al proceso y el.
UPCy uso de memoria y otra información. Familiarizarse con cómo verlos puede ayudar con análisis estadísticos relevantes y otras operaciones.
Vea las propiedades de todos los procesos actuales en el sistema:
$ ps-ef
Ver el proceso correspondiente al programa que contiene un determinado carácter en el comando, proceso
IDENTIFICACIÓNes 1.
TTY¿para? Indica que no está relacionado con el terminal:
$ ps -C inicio PID TTY TIME CMD 1 00:00:01 inicio?
Seleccionar procesos iniciados por un usuario específico:
$ ps -U halcón
Genere el contenido especificado de acuerdo con el formato especificado. Lo siguiente genera el nombre del comando y.
UPCTasa de uso:
$ ps -e -o %C %c
Imprimir
UPCLos 4 programas más utilizados:
$ ps -e -o %C %c | ordenar -u -k1 -r | cabeza -5 7.5 firefox-bin 1.1 Xorg 0.8 scim-panel-gtk 0.2 scim-bridge
Obtenga los cinco procesos utilizando la memoria virtual más grande:
$ ps -e -o %z %c | ordenar -n -k1 -r | cabeza -5349588 firefox-bin 96612 xfce4-terminal 88840 xfdesktop 76332 gedit 58920 scim-panel-gtk
Existe una relación de "parentesco" entre todos los procesos del sistema, que puede ser
ptreeMira esta relación:
$ ptree
El árbol de llamadas de procesos del sistema se imprimirá arriba y podrá ver claramente la relación de llamadas entre todos los procesos activos en el sistema actual.
$ superior
La característica más importante de este comando es que puede ver dinámicamente la información del proceso. Por supuesto, también proporciona algunos otros parámetros, como.
-SPuede ordenarlos y verlos según el tiempo de ejecución acumulado, o puede utilizar
-túVer procesos iniciados por un usuario específico, etc.
Reponer:
arribaEl comando admite interactivo, por ejemplo admite
tuEl comando muestra todos los procesos del usuario y admite el paso
kComando para matar un proceso si se usa;
-norte 1opción para habilitar el modo de procesamiento por lotes, el uso específico es:
$ arriba -n 1 -b
Analicemos un problema interesante: cómo hacer que solo se ejecute un programa al mismo tiempo.
Esto significa que mientras se ejecuta un programa no se puede volver a iniciar. Entonces, ¿qué hacer?
Si el mismo programa se copia en muchas copias y tiene diferentes nombres de archivo y se coloca en diferentes ubicaciones, esto será peor, así que considere el caso más simple, es decir, este programa es único en todo el sistema y el nombre también es único. . En este caso, ¿cuáles son algunas formas de responder las preguntas anteriores?
El mecanismo general es: verificar al comienzo del programa si se ha ejecutado. Si se ejecuta, deténgase; de lo contrario, continúe ejecutando el código posterior.
Las estrategias son diversas, ya que la suposición anterior ha garantizado la unicidad del nombre y el código del archivo del programa.
PDEl comando encuentra los nombres de los programas correspondientes a todos los procesos actuales y los compara con su propio nombre de programa uno por uno. Si ya existe, significa que ya se ha ejecutado.
ps -e -o %c | tr -d | grep -q ^init$ #Verifique si el programa actual se ejecuta [ $? -eq 0 ] && exit #Si es así, salga, $? fue ejecutado exitosamente
Cada vez que se ejecuta, primero verifique si hay un proceso que se guarda solo en la ubicación especificada.
IDENTIFICACIÓNarchivo, si no existe, entonces continuar la ejecución, si existe, entonces ver el proceso
IDENTIFICACIÓN¿Se está ejecutando? Si es así, salga; de lo contrario, vuelva a escribir el nuevo proceso en el archivo.
IDENTIFICACIÓNy continuar.
pidfile=/tmp/$0.pidif [ -f $pidfile ]; luego OLDPID=$(cat $pidfile) ps -e -o %p | tr -d | && exitfiecho $$ > $pidfile#... Cuerpo del código# Establece la acción de la señal 0. Cuando el programa sale, la señal se activa para eliminar el archivo temporal trap rm $pidfile 0
¡Siéntete libre de utilizar más estrategias de implementación tú mismo!
Además de garantizar que cada proceso se pueda ejecutar sin problemas, para permitir que ciertas tareas se completen primero, el sistema utilizará ciertos métodos de programación al programar procesos, como el algoritmo de programación común de rotación de intervalos de tiempo según la prioridad. En este caso, puedes pasar
reniceAjuste la prioridad de un programa en ejecución, por ejemplo: `
$ ps -e -o %p %c %n | grep xfs 5089 xfs 0
$ renice 1 -p 5089renice: 5089: setpriority: Operación no permitida$ sudo renice 1 -p 5089 #Se requieren permisos [sudo] contraseña para falcon:5089: antigua prioridad 0, nueva prioridad 1$ ps -e -o %p % c %n | grep xfs #Mira de nuevo, la prioridad ha sido ajustada 5089 xfs 1
Dado que puede ejecutar un programa y crear un proceso a través de la línea de comando, también existe una manera de finalizarlo. puede pasar
matarEl comando envía una señal al proceso iniciado por el usuario para finalizar el proceso. Por supuesto, es "universal".
raízcasi
matarTodos los procesos (excepto
inicioafuera). Por ejemplo,
$ dormir 50 & #Iniciar un proceso [1] 11347$ matar 11347
matarEl comando enviará una señal de terminación de forma predeterminada (
SIGNO) al programa y dejar que el programa salga, pero
matarTambién se pueden enviar otras señales y éstas se pueden definir mediante
señal del hombre 7También puedes verlo a través
matar -lEnumérelo.
$ man 7 señal$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR213) SIGPIPE 14) SIGALRM 15 ) SIGNO 16) SIGSTKFLT17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+439) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+843) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+1247) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-1451) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-1055) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-659) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-263) SIGRTMAX-1 64) SIGRTMAX
Por ejemplo, utilice
matarcomando para enviar
SIGSTOPSeñalar un programa para que se detenga y luego se envíe
SEÑAL CONTLa señal lo mantiene funcionando.
$ sleep 50 &[1] 11441$ jobs[1]+ Ejecutando sleep 50 &$ kill -s SIGSTOP 11441 #Esto es equivalente a que realicemos la operación CTRL+Z en un proceso en primer plano $ jobs[1]+ Sleep detenido 50$ kill -s SIGCONT 11441 #Esto es equivalente a la operación bg %1 anterior que usamos para ejecutar un proceso en segundo plano $ jobs[1]+ Ejecutando sleep 50 &$ kill %1 #En la sesión actual, también puede controlar el proceso a través del número de trabajo $ jobs[1]+ Terminado el sueño 50
visible
matarEl comando proporciona muy buenas funciones, pero solo puede basarse en el proceso.
IDENTIFICACIÓNo trabajo para controlar el proceso, mientras
matary
matar a todosSe proporcionan más opciones que amplían las formas de controlar un proceso por su nombre de programa o incluso su nombre de usuario. Consulte sus manuales para obtener más información sobre su uso.
Cuando el programa sale, ¿cómo determinar si el programa salió normal o anormalmente? ¿Aún recuerdas ese clásico en Linux?
Hola Mundo¿Programa? Al final del código siempre hay una línea.
regresar 0declaración. este
regresar 0De hecho, permite al programador comprobar si el proceso finaliza normalmente. Si el proceso devuelve un valor diferente, entonces se puede decir con seguridad que el proceso salió de forma anormal porque aún no se ha ejecutado.
regresar 0Esta declaración existe.
Entonces, ¿cómo verificar el estado de salida del proceso, es decir, el valor devuelto?
existir
Caparazón, puedes comprobar esta variable especial
$?, que almacena el estado de salida después de que se ejecutó el comando anterior.
$ test1bash: test1: comando no encontrado$ echo $?127$ cat ./test.c | hola$ echo $?1$ cat ./test.c | hola printf(¡hola, yo mismo!n);$ echo $?0
Parece que devolver 0 se ha convertido en una regla tácita. Aunque no existe un estándar que lo estipule claramente, cuando el programa regresa normalmente, siempre se puede devolver.
$?Se detecta 0 en , pero cuando es anormal, siempre se detecta un valor distinto de 0. Esto nos indica que al final del programa lo mejor es seguir las
salir 0para que cualquiera pueda pasar la prueba
$?Determine si el programa finaliza normalmente. Si un día alguien usa ocasionalmente su programa e intenta verificar su estado de salida, pero inexplicablemente usted devuelve un
-1O 1, entonces estará muy angustiado y se preguntará dónde está el problema en el programa que él mismo escribió. Lo comprobará durante mucho tiempo pero estará perdido porque confía tanto en usted que nunca duda de sus hábitos de programación. de principio a fin. ¡Será diferente!
Para facilitar el diseño y la implementación, una tarea grande generalmente se divide en módulos más pequeños. Los diferentes módulos se convierten en procesos una vez iniciados. ¿Cómo se comunican entre sí para intercambiar datos y trabajar juntos? En el libro "Programación avanzada en entorno UNIX" se mencionan muchos métodos, como canalizaciones (canalizaciones sin nombre y canalizaciones con nombre), señales (
señal), mensaje (
Mensaje) cola (cola de mensajes), memoria compartida (
mmap/munmap), semáforo (
semáforo, utilizado principalmente para sincronización, entre procesos, entre diferentes subprocesos de un proceso), sockets (
Enchufe, admite la comunicación de procesos entre diferentes máquinas), etc., y en Shell, las tuberías y señales generalmente se usan directamente. A continuación se presentan principalmente algunos usos de canalizaciones y mecanismos de señales en la programación de Shell.
En Linux, puedes pasar
|Conecte dos programas para que pueda usarlo para conectar la entrada del último programa a la salida del programa anterior, por eso se le llama vívidamente tubería. En lenguaje C, es muy simple y conveniente crear una tubería sin nombre.
tubofunción, pasando un elemento de dos elementos
enteroUna variedad de tipos servirá. Esta matriz en realidad almacena dos descriptores de archivo. Después de que el proceso principal escribe algo en el primer descriptor de archivo, el proceso secundario puede leerlo desde el primer descriptor de archivo.
Si usa demasiadas líneas de comando, esta tubería
|Se debe utilizar con frecuencia. Por ejemplo, hay una demostración arriba.
PDLa salida del comando es como
grepEntrada de comando:
$ ps -ef |
Quizás pienses que esta "tubería" es tan mágica que en realidad puede vincular la entrada y la salida de dos programas. ¿Cómo se implementan? De hecho, cuando se ingresa dicho conjunto de comandos, el shell actual realizará el análisis apropiado, asociará la salida del proceso anterior con el descriptor del archivo de salida de la tubería y asociará la entrada del proceso posterior con el descriptor del archivo de entrada de la tubería. Este proceso de asociación redirige las funciones a través de entrada y salida.
duplicar(o
fcntl) para lograr.
Una canalización con nombre es en realidad un archivo (una canalización sin nombre también es como un archivo. Aunque está relacionada con dos descriptores de archivo, solo se puede leer por un lado y escribir por el otro). debe cumplir primero en entrar, primero en salir durante la operación y, si intenta leer desde una canalización con nombre que no tiene contenido, será bloqueado. Del mismo modo, si intenta escribir en una canalización con nombre y ningún programa lo está intentando actualmente. Para leerlo, serás bloqueado. Vea el efecto a continuación.
$ mkfifo fifo_test #Crea una tubería famosa a través del comando mkfifo $ echo lessfefe > fifo_test #Intentando escribir contenido en el archivo fifo_test, pero está bloqueado Necesita abrir otra terminal para continuar con las siguientes operaciones $ cat fifo_test #Abre otra terminal. , recuerda, abre otro. Intentando leer el contenido de fifo_test lessfefe
Aquí está
ecoy
gatoSon dos programas diferentes, en este caso, por
ecoy
gatoNo existe una relación padre-hijo entre los dos procesos iniciados. Sin embargo, aún pueden comunicarse a través de canalizaciones con nombre.
Este método de comunicación es muy adecuado para determinadas situaciones: por ejemplo, existe una arquitectura de este tipo que consta de dos aplicaciones, una de las cuales lee continuamente a través de un bucle.
quince_pruebacontenido para determinar qué debe hacer a continuación. Si esta tubería no tiene contenido, entonces quedará bloqueada allí sin consumir recursos debido a un bucle infinito. La otra seguirá fluyendo como programa de control.
quince_pruebaEscriba alguna información de control en él para indicarle al programa anterior qué hacer. Escribe un ejemplo muy simple a continuación. Puede diseñar algunos códigos de control y luego el programa de control continúa
quince_pruebaEscriba en él y luego la aplicación completa diferentes acciones basadas en estos códigos de control. Por supuesto, también puedes ir a
quince_pruebaPase otros datos excepto el código de control.
código de aplicación
$ cat app.sh #!/bin/bash FIFO=fifo_test while :; do CI=`cat $FIFO` #CI --> Información de control caso $CI en 0) echo El número de CONTROL es CERO, haz algo... ;; 1) echo El número de CONTROL es UNO, haz algo... ;; *) echo El número de CONTROL no se reconoce, haz algo más... ;;
Código del programa de control
$ cat control.sh #!/bin/bash FIFO=fifo_test CI=$1 [ -z $CI ] && echo la información de control no debe estar vacía && exit echo $CI > $FIFO
Un programa controla el trabajo de otro programa a través de tuberías.
$ chmod +x app.sh control.sh #Modificar los permisos ejecutables de estos dos programas para que los usuarios puedan ejecutarlos $ ./app.sh #Iniciar esta aplicación en una terminal y enviar el control a través de ./control.sh Verificar la salida después del código el número de CONTROL es UNO, haga algo más... #Después de enviar 1, el número de CONTROL es CERO, haga algo... #Después de enviar 0, el número de CONTROL no se reconoce, haga algo más... #Enviar un código de control desconocido después $ ./control.sh 1 #En otra terminal, enviar información de control para controlar el trabajo de la aplicación $ ./control.sh 0 $ ./control.sh 4343
Esta arquitectura de aplicación es muy adecuada para el diseño de tareas locales de múltiples programas si se combina con ella.
cgi web, entonces también se adaptará a los requisitos del control remoto. introducir
cgi webEl único cambio es que el programa de control
./control.shmeter en
webde
cgidirectorio y realizar algunas modificaciones para que se ajuste a
CGIespecificaciones, que incluyen una representación del formato de salida del documento (es necesario generar al principio del archivo
tipo de contenido: texto/htmly una línea en blanco) y la adquisición de parámetros de entrada
(webLos parámetros de entrada se almacenan en
QUERY_STRINGvariables de entorno). Entonces algo muy simple
CGIEl programa de control se puede escribir así:
#!/bin/bashFIFO=./fifo_testCI=$QUERY_STRING[ -z $CI ] && echo la información de control no debe estar vacía && exitecho -e content-type: text/htmlnnecho $CI > $FIFO
En uso real, asegúrese de
control.shcapaz de acceder
quince_pruebapipe, y tiene permisos de escritura para el control a través del navegador
aplicación.sh:
http://direcciónip_or_dns/cgi-bin/control.sh?0
signo de interrogación
?El siguiente contenido es
QUERY_STRING, similar al anterior
$1.
Una aplicación de este tipo tiene una gran importancia práctica para el control remoto, especialmente para el control remoto de sistemas integrados. En el curso de verano del año pasado implementamos el control remoto de motores de esta manera. En primer lugar, se implementa una aplicación sencilla para controlar la rotación del motor, incluyendo control de velocidad, dirección, etc. Para lograr el control remoto, diseñamos algunos códigos de control para controlar diferentes propiedades relacionadas con la rotación del motor.
En lenguaje C, si desea utilizar una canalización con nombre, es similar a Shell, excepto que al leer y escribir datos, use
leer,
escribirllamar, crear
quinceañeraUsado cuando
mkfifollamada a función.
Las señales son interrupciones de software a las que los usuarios de Linux pueden acceder a través de
matarEl comando envía una señal específica a un proceso, o algunas señales se pueden enviar a través del teclado, como
CTRL+Cpuede desencadenar
SGIINTseñal, mientras
CTRL+puede desencadenar
SGIQUITSeñales, etc. Además, el kernel también enviará señales al proceso en determinadas circunstancias, como cuando se accede a la memoria fuera de los límites.
SGISEGVLas señales, por supuesto, y el proceso en sí también pueden pasar.
matar,
aumentarEspere a que la función se envíe una señal a sí misma. Para los tipos de señal admitidos en Linux, puede pasar
señal del hombre 7o
matar -lConsulte listas e instrucciones relacionadas.
Para algunas señales, el proceso tendrá acciones de respuesta predeterminadas, mientras que para algunas señales, el proceso puede simplemente ignorarlas. Por supuesto, los usuarios también pueden configurar funciones de procesamiento especiales para ciertas señales. En el caparazón, puedes pasar.
trampacomando (comando incorporado de Shell) para establecer una acción en respuesta a una señal (un comando o una función definida), y en lenguaje C puede usar
señalLlame a la función de controlador registrada para una señal. Esto es solo una demostración
trampaUso del comando.
$ function signal_handler { echo hola, mundo } #Defina la función signal_handler $ trap signal_handler SIGINT #Ejecute esta configuración de comando: imprima hola, mundo al recibir la señal SIGINT $ hola, mundo #Presione CTRL+C para ver la pantalla Hola y se emiten cadenas mundiales
De manera similar, si configura la acción de respuesta de la señal 0, puede usar
trampaPara simular el programa en lenguaje C.
atexitRegistro de la función de terminación del programa, es decir, a través de
trampa signal_handler SIGQUITcolocar
controlador_señalLa función se ejecutará cuando el programa salga. La señal 0 es una señal especial en
POSIX.1La señal número 0 se define como una señal nula, que a menudo se utiliza para determinar si un proceso específico todavía existe. Esta señal se activa cuando sale un programa.
$ cat sigexit.sh#!/bin/bashfunction signal_handler { echo hola, mundo}trap signal_handler 0$ chmod +x sigexit.sh$ ./sigexit.sh # La programación real de Shell utilizará este método para realizar una limpieza cuando el programa salga Terminando el trabajo en archivos temporales hola mundo
Cuando pasamos múltiples comandos a través
|,>,<, ;, (,)Cuando se combinan, esta secuencia de comandos generalmente inicia múltiples procesos que se comunican a través de tuberías, etc. A veces, al ejecutar una tarea, hay otras tareas que deben procesarse, por lo que a menudo agrega un & al final de la secuencia de comando, o después de ejecutar el comando, presiona
CTRL+ZHace que el comando anterior se detenga. para realizar otras tareas. Después de completar algunas otras tareas, pase
fgEl comando cambia la tarea en segundo plano al primer plano. Este proceso de control suele denominarse control de trabajos, y esas secuencias de comandos se denominan trabajos. Este trabajo puede implicar uno o más programas, uno o más procesos. A continuación se muestran varias operaciones de control de trabajos comúnmente utilizadas.
$ dormir 50 &[1] 11137
Utilice los comandos integrados de Shell
fgTraiga el trabajo 1 al primer plano y presione
CTRL+ZPausar el proceso
$ fg %1sleep 50^Z[1]+ Detuvo el sueño 50
$ trabajos # Verifique el estado del trabajo actual, un trabajo está detenido [1] + Detuvo la suspensión 50$ suspensión 100 & # Deje que otro trabajo se ejecute en segundo plano [2] 11138$ trabajos # Verifique el estado actual del trabajo, uno se está ejecutando y el otro está detenido [1]+ Detenido el sueño 50[2]- Ejecutando el sueño 100 &
$ bg %1[2]+ dormir 50 &
Sin embargo, para utilizar el control de trabajos bajo la línea de comando, el shell actual, el controlador del terminal del kernel, etc. deben admitir el control de trabajos.
"Programación Avanzada en Entorno UNIX"