[Linux] Basic IO --- enlaces flexibles y duros, tiempo acm, creación de bibliotecas estáticas y dinámicas, enlaces estáticos y dinámicos, principios de carga de bibliotecas estáticas y dinámicas...

Quemé todo el infantilismo y la obstinación con mi persistencia, y el desierto creció lentamente en indiferencia racional y sobriedad.

inserte la descripción de la imagen aquí

Directorio de artículos



1. Enlaces blandos y duros

tipo de archivo linux ilustrar
b Los archivos de dispositivos de bloque generalmente se refieren a dispositivos de almacenamiento como discos duros y disquetes.
C Los dispositivos de caracteres son algunos dispositivos de interfaz de puerto serie, como teclados, ratones, impresoras y terminales tty.
d Archivos de directorio, similares a las carpetas de Windows.
yo Vincular archivos, similar a los accesos directos de Windows.
s Archivo de socket (socket), utilizado principalmente para la comunicación, especialmente en la red.
pag Archivo de canalización (tubería), utilizado principalmente para la comunicación entre procesos
- Los archivos se dividen en archivos de texto sin formato (ASCII) y archivos binarios (binary).

1. La diferencia entre enlaces blandos y duros (si tiene un inodo independiente)

1. Los siguientes son los resultados de enlaces blandos y enlaces duros respectivamente.

[wyn@VM-8-2-centos lesson21]$ ln -s myfile.txt soft_file.link ---软链接

inserte la descripción de la imagen aquí

[wyn@VM-8-2-centos lesson21]$ ln myfile.txt hard_file.link ---硬链接

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
2.
El archivo de vínculo suave soft_file.link tiene su propio inodo independiente y se puede tratar como un archivo independiente .
El archivo de enlace fijo no tiene su propio inodo independiente. No importa qué contenido se cambie en myfile.txt, hard_file.link cambiará a la vez. Por lo tanto, cuando se establece un enlace fijo, no se crea ningún archivo nuevo en absoluto, porque no el inodo independiente se asigna al enlace duro .

3.
Dado que el vínculo físico no crea un nuevo archivo, el vínculo físico no debe tener su propio conjunto de atributos y conjunto de datos, y debe usar inodos y bloques de datos de otros archivos, por lo que la esencia del vínculo físico es agregar archivos bajo la ruta especificada La relación de mapeo entre el nombre y el inodo, varios archivos apuntan al inodo .

inserte la descripción de la imagen aquí

4.
Entonces, el recuento de referencias (también llamado número de enlaces duros) que muestra 791188 es 2, porque hay dos archivos que apuntan al inodo 791188.

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

5.
Después de eliminar el archivo myfile.txt, la cantidad de enlaces duros del archivo hard_file.link se convertirá naturalmente en 1, por lo que cuando la cantidad de enlaces duros de un archivo sea 0, el archivo se eliminará, como myfile.txt El número de enlaces duros se ha convertido en 0 .

inserte la descripción de la imagen aquí

2. El papel de los enlaces blandos y duros

2.1 El papel de los enlaces blandos (creación de accesos directos)

1.
Después de eliminar el archivo de destino myfile.txt del enlace suave, el enlace suave todavía existe porque su inodo todavía está allí, pero cuando cat imprime el archivo de enlace suave, muestra que el archivo no existe. Entonces, el enlace suave soft_file.link no usa el inodo del archivo de destino para identificar el archivo de destino, porque el inodo del archivo fuente todavía existe. ¿El enlace duro hard_file.link usa el inodo del archivo fuente? Se puede ver que el enlace suave identifica el archivo de origen utilizando el nombre del archivo de origen .

2.
El bloque de datos del vínculo de software guarda la ruta del archivo de destino al que apunta , por lo que una vez que se elimina el archivo de origen, el vínculo de software dejará de ser válido de inmediato porque no puede encontrar el archivo de destino.

inserte la descripción de la imagen aquí

3.
Eliminar el enlace suave no afecta el archivo de origen, por lo que el enlace suave es equivalente a un acceso directo en Windows.
Hay un destino en el atributo de borde, que en realidad es equivalente al archivo de destino señalado en el enlace suave.La razón por la que podemos hacer doble clic en el acceso directo para abrir Microsoft Edge es que el archivo de destino es en realidad el programa ejecutable de Microsoft. borde _
Si cada vez que ejecutamos un programa, tenemos que encontrar la ruta específica del disco donde se descarga el programa y luego hacer doble clic en el programa ejecutable para ejecutarlo, para que todos los usuarios se vuelvan locos, también es difícil de usar, es demasiado repugnante, por lo que existe un atajo, que es muy similar al enlace suave de linux .

[wyn@VM-8-2-centos lesson21]$ unlink soft_file.link ---删除软链接文件

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

4.
La imagen a continuación muestra la función del enlace suave, que es establecer un enlace suave para un programa ejecutable en un directorio profundo en un directorio específico, y luego puede ejecutar rápidamente el programa ejecutable en el directorio especificado.

inserte la descripción de la imagen aquí

2.2 El papel de los enlaces duros (para evitar la eliminación accidental de archivos importantes, búsqueda rápida y cambio de rutas (. y . .))

1.
En la superficie, el vínculo físico parece un cambio de nombre del archivo de origen, al igual que el clon del archivo de origen. La función real del vínculo físico es permitir que un archivo tenga múltiples nombres de ruta válidos, de modo que el usuario puede establecer un enlace duro a archivos importantes para evitar la función de "borrado accidental".
Suponiendo que myfile.txt es un archivo muy importante, estableceremos un enlace fijo a myfile.txt para formar el archivo hard_file.txt, por lo que incluso si eliminamos el archivo myfile.txt por error, no se preocupe, porque los datos en hard_file.txt y myfile .txt es exactamente lo mismo, lo que equivale a hacer una copia de seguridad de los datos de un archivo importante.

inserte la descripción de la imagen aquí

2.
El archivo file.txt solo apunta a su propio inodo, por lo que su número de enlace fijo es 1. El archivo de directorio vacío no solo apunta a su propio inodo, sino también a los archivos ocultos debajo del directorio. del archivo de directorio vacío, tan vacío El número de enlaces duros es 2, porque hay dos archivos que apuntan al inodo vacío.
Si crea otro directorio en vacío, la cantidad de enlaces duros en vacío será 3, porque los archivos ocultos en dir... también apuntan al inodo de vacío, por lo que los archivos ocultos en el directorio vacío y los archivos ocultos
en el directorio dir en el directorio vacío El archivo... es en realidad equivalente al enlace físico del archivo del directorio vacío.

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

3.
Conocimiento adicional: el tamaño de los archivos de directorio es un múltiplo de 4096 bytes, el mínimo es 4096, porque 4096 es un bloque IO, y la unidad más pequeña de lectura y escritura de disco es 8 sectores, que es exactamente 4096 bytes de tamaño. El sistema operativo sabe que definitivamente leerá y escribirá archivos en el archivo del directorio, por lo que abre directamente un espacio del tamaño de un bloque de IO para usted .

En el siguiente artículo, hay algunos errores sobre las unidades, que deben verse dialécticamente.
¿Por qué el tamaño del directorio siempre es 4096 en Linux?

4.
Como se puede ver a continuación, Linux no permite que los usuarios comunes creen enlaces duros a directorios, pero el propio Linux puede crear enlaces duros (archivos ocultos) a directorios. Solo los funcionarios estatales pueden prender fuego y la gente común puede hacerlo. No se permite encender lámparas.

¿Por qué Linux no puede vincular directorios? (Reimpreso del artículo de Zhihu blogger Zuiwo battlefield blogger, la explicación es muy, muy, muy detallada )

¿Por qué ln no puede enlazar directorios en circunstancias normales? (reproducido del artículo del blogger Kproxy)

inserte la descripción de la imagen aquí
5.
Sin embargo, los directorios de enlace suave están permitidos. Si desea cancelar el directorio de enlace suave, puede usar desvincular, pero debe tener en cuenta que / no se puede agregar al final del archivo, porque el archivo de enlace suave no es un directorio sino un archivo .

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

Comparta un artículo bien escrito, los socios interesados ​​pueden leerlo.
Enlace suave y enlace duro de Linux (reproducido del artículo sobre el león de asedio back-end del blogger Heropoo)

Segundo, el tiempo acm bajo el comando stat

inserte la descripción de la imagen aquí
1.
Acceso se refiere al momento en que se accede al archivo.
Cambio se refiere al momento en que se modifican los atributos del archivo.
Modificar se refiere al momento en que se modifica el contenido del archivo.

2.
Si modifica el contenido del archivo, el tamaño del archivo en las propiedades del archivo también cambiará en consecuencia , por lo que a menudo vemos que después de modificar el contenido del archivo, el cambio se modificará junto con el tiempo de modificación.

3.
En el sistema operativo Linux en los primeros años, siempre que accediera al archivo, el tiempo de acceso del archivo cambiaría inmediatamente, pero luego descubrió que la tasa de cambios de atributos y contenidos en las operaciones de archivos es mucho mayor que eso. de acceder a los archivos , por lo que si el tiempo de acceso al archivo debe actualizarse cada vez, los datos IO frecuentes afectarán la eficiencia del sistema operativo, porque el disco es un periférico.
Por lo tanto, Linux cambió la estrategia original, por ejemplo, cuando el número de visitas alcanza un cierto número fijo, Linux actualizará el tiempo de acceso del archivo de manera uniforme, por lo que el tiempo de acceso no se actualiza en tiempo real .

3. La diferencia entre bibliotecas dinámicas y estáticas (etapa de enlace, resultado de enlace, diferencia en el método de enlace)

1.
La biblioteca estática tiene el sufijo .a, y el programa vincula el código de la biblioteca al archivo ejecutable durante la fase de compilación y vinculación. Cuando el programa se ejecuta y se carga en la memoria para convertirse en un proceso, la biblioteca estática ya no será necesaria.
La biblioteca dinámica tiene el sufijo .so. Cuando el programa se carga en la memoria y se convierte en un proceso, el código de la biblioteca dinámica se vinculará. Si hay varios procesos en la memoria que necesitan la biblioteca dinámica, varios procesos compartirán el código usando la biblioteca dinámica. .

2.
El archivo ejecutable que usa el enlace dinámico solo contiene una tabla de las direcciones de entrada de las funciones que usa, no el código de máquina completo de las funciones externas en el archivo de la biblioteca.

3.
Después de que el archivo ejecutable se cargue en la memoria y se convierta en un proceso, el sistema operativo copiará el código de máquina de la función externa del archivo de biblioteca en el disco a la memoria.Este proceso se denomina vinculación dinámica.

4.
La biblioteca dinámica se puede compartir entre varios procesos, por lo que el archivo ejecutable vinculado dinámicamente es más pequeño y ahorra espacio en disco. El mecanismo de memoria virtual adoptado por el sistema operativo permite que múltiples procesos compartan una biblioteca dinámica en la memoria física , ahorrando espacio en la memoria.

4. ¿Cuál es la naturaleza de la biblioteca? (una colección de archivos .o)

A continuación se escriben algunos códigos simples que pueden ayudarnos a comprender qué es una biblioteca y qué hace.
inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí
1.
Las dos formas de generar el programa ejecutable mymath son en realidad las mismas. Una integra el proceso de compilación y vinculación, y la otra separa el proceso de compilación y vinculación. Primero, cada archivo fuente se compila para generar un archivo binario de destino reubicable, y luego se vinculan los archivos Múltiples .o, es decir, la tabla de símbolos se fusiona y el método de vinculación se puede subdividir en vinculación dinámica y vinculación estática.

1.gcc -o mymath main.c my_sub.c my_add.c

2.gcc -c main.c 
gcc -c my_sub.c
gcc -c my_add.c
gcc -o mymath main.o my_sub.o my_add.o

2.
Si no queremos dar el código fuente a la otra parte, podemos proporcionar a la otra parte el archivo binario de destino reubicable .o y el archivo de encabezado .h, y dejar que la otra parte realice directamente el trabajo de vinculación. Este método también puede generar programas ejecutables.
El lado izquierdo es equivalente a la persona que usa la biblioteca y el lado derecho es equivalente a la persona que escribió la biblioteca.
La idea de proporcionar a la otra parte una colección de .o (implementación del método) y .h (qué métodos hay) es la idea de la biblioteca.

inserte la descripción de la imagen aquí

3.
Una vez que hay demasiados archivos de origen que deben compilarse, todos los archivos .o se pueden empaquetar en un solo paquete para mayor comodidad, y el paquete que contiene un montón de archivos .o es en realidad un archivo de biblioteca. y método de empaquetado Diferente se puede dividir en biblioteca dinámica y biblioteca estática, la esencia de la biblioteca es una colección de archivos .o .

5. Biblioteca estática y enlace estático (comando ar, archivar el archivo .o)

1. Cree una biblioteca estática (empaquetar y comprimir archivos .h y .o para formar una colección de archivos de encabezado y archivos de biblioteca)

inserte la descripción de la imagen aquí
Explicación detallada del comando tar, empaquetado, compresión y desempaquetado
1.
El comando ar son en realidad las dos primeras letras de la palabra archivo y la biblioteca estática es el archivo de almacenamiento.
rc significa reemplazar y crear.Si el archivo empaquetado no existe, el archivo se creará y, si existe, se reemplazará en el archivo de almacenamiento.
El archivo libmymath.a generado ahora es un archivo.

inserte la descripción de la imagen aquí

  1 libmymath.a:my_add.o my_sub.o
  2     ar -rc $@ $^    ---生成静态库libmymath.a
  3 my_add.o:my_add.c
  4     gcc -c my_add.c
  5 my_sub.o:my_sub.c
  6     gcc -c my_sub.c
  7 
  8 .PHONY:clean
  9 clean:
 10     rm -f *.o libmymath.a      

inserte la descripción de la imagen aquí

2.
No es suficiente tener libmymath.a (archivo de biblioteca escrito por nosotros mismos), porque el lenguaje C proporcionará a los usuarios el archivo de biblioteca libc.a y el archivo de encabezado stdio.h, por lo que todavía nos faltan archivos de encabezado.
La realidad de entregar la biblioteca a la otra parte es entregar tanto el archivo de la biblioteca (.a/.so) como el archivo de encabezado coincidente a la otra parte.

[wyn@VM-8-2-centos lesson22]$ ls /usr/include/stdio.h
/usr/include/stdio.h
[wyn@VM-8-2-centos lesson22]$ ls /lib64/libc.a
/lib64/libc.a

3.
Después de ejecutar make output, se puede generar una biblioteca. El nombre de la biblioteca es mylib, que contiene archivos de biblioteca y archivos de encabezado. Mylib se puede usar como un archivo de biblioteca para que lo use la otra parte.
Si el archivo de la biblioteca es de gran tamaño, también se puede entregar al usuario en forma de paquete comprimido.

  1 libmymath.a:my_add.o my_sub.o
  2     ar -rc $@ $^    ---生成静态库libmymath.a
  3 my_add.o:my_add.c
  4     gcc -c my_add.c
  5 my_sub.o:my_sub.c
  6     gcc -c my_sub.c
  7 
  8 .PHONY:output
  9 output:
 10     mkdir -p mylib/include 
 11     mkdir -p mylib/lib
 12     cp -f *.a mylib/lib 
 13     cp -f *.h mylib/include                                                                                                           
 14 .PHONY:clean
 15 clean:
 16     rm -f *.o libmymath.a

inserte la descripción de la imagen aquí

Comprima la biblioteca mylib en un paquete comprimido mylib.tgz. Al entregar la biblioteca, puede entregar este paquete comprimido a la otra parte.

[wyn@VM-8-2-centos lesson22]$ tar -czvf mylib.tgz mylib

inserte la descripción de la imagen aquí

Al eliminar varios archivos, podemos usar el comodín * para una eliminación eficiente.

inserte la descripción de la imagen aquí

La persona que usa la biblioteca de la izquierda puede obtener la biblioteca mylib después de descomprimir el paquete comprimido.

inserte la descripción de la imagen aquí

4.
Si la persona que usa la biblioteca quiere instalar la biblioteca, solo necesita copiar los archivos correspondientes al directorio del sistema, por lo tanto, la esencia de la instalación es copiar.

[wyn@VM-8-2-centos test]$ cp mylib/include/*.h /usr/include/
[wyn@VM-8-2-centos test]$ cp mylib/lib/libmymath.a /lib64/

2. Después de que el usuario obtenga la biblioteca, los problemas encontrados al compilar y vincular

2.1 gcc no puede encontrar el archivo de encabezado

1.
Si el usuario compila y vincula directamente con gcc, se producirá un error que indica que no se puede encontrar el archivo de encabezado.
Cuando el compilador gcc busca archivos de encabezado, hay dos estrategias de búsqueda, una es buscar en la ruta actual (ruta del mismo nivel que el código fuente), y la otra es buscar en la ruta predeterminada especificada por el sistema , y ​​gcc realmente no puedo encontrarlo en la ruta actual a los archivos de encabezado dentro de la biblioteca mylib.

inserte la descripción de la imagen aquí
2.
Entonces, debemos usar la opción -I para especificar la ruta de búsqueda del archivo de encabezado gcc,

[wyn@VM-8-2-centos test]$ gcc -o mymath main.c -I ./mylib/include/

2.2 Error de enlace: referencia indefinida a la función (archivo de biblioteca no encontrado, ruta de búsqueda de biblioteca)

1.
Se produce un error de enlace después de ejecutar la instrucción, es decir, no hay ningún problema en las etapas de preprocesamiento, compilación y ensamblaje.
Si el archivo de biblioteca está en la ruta del sistema (ruta /usr/lib64 o /usr/lib), el enlazador definitivamente puede encontrar el archivo de biblioteca correspondiente, pero el enlazador no puede encontrar el archivo de biblioteca en la ruta actual.

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

2.
Por lo tanto, debe usar la opción -L para especificar la ruta de búsqueda del enlazador. Pero además de eso, se debe especificar el nombre de la biblioteca.
Porque si desea vincular una biblioteca de terceros, debe especificar explícitamente el nombre de la biblioteca .

[wyn@VM-8-2-centos test]$ gcc -o mymath main.c -I ./mylib/include/ -L ./mylib/lib/

Simplemente especifique la ruta del archivo de la biblioteca, el sistema aún informa un error de enlace.
inserte la descripción de la imagen aquí

3.
El archivo de encabezado no necesita especificar el nombre del archivo de encabezado, solo se requiere la ruta del archivo de encabezado. Esto se debe a que el código fuente main.c le dice al compilador qué archivo de encabezado incluir, y gcc irá a la ruta especificada para encontrar un documento de encabezado específico.
Pero nadie le dice al enlazador qué archivo de biblioteca vincular, por lo que tenemos que especificar la ruta y el nombre del archivo de biblioteca.

4.
Pero cuando escribimos el código antes, nunca especificamos el nombre de la biblioteca. Eso es porque no usamos una biblioteca de terceros en ese momento. Usamos la biblioteca estándar proporcionada por el lenguaje C o C++, o el sistema nivel proporcionado por la interfaz del sistema operativo, por lo que gcc o g ++ pueden determinar qué archivo de biblioteca debe vincular el código de forma predeterminada , pero la biblioteca que vinculamos hoy no es una biblioteca estándar, sino una biblioteca de terceros.

Biblioteca propia:
biblioteca de segunda parte del sistema:
biblioteca propia de terceros: escrita por otros

5.
Al usar la opción -l para especificar el nombre de la biblioteca, se deben eliminar el prefijo lib y el sufijo .a o .so del archivo de la biblioteca, y el resto en el medio es el nombre del archivo de la biblioteca.

inserte la descripción de la imagen aquí
Entre la opción y el contenido detrás de la opción, si hay un espacio o no es aceptable, y la función de autocompletar sin espacios se perderá, pero se verá más compacto sin espacios.

[wyn@VM-8-2-centos test]$ gcc -o mymath main.c -I./mylib/include/ -L./mylib/lib/ -lmymath

Después de eliminar el prefijo y el sufijo, la biblioteca mylib se puede usar normalmente.
inserte la descripción de la imagen aquí

2.3 ¿De qué depende el método de vinculación específico? (dependiendo de las bibliotecas proporcionadas y las opciones compiladas con)

1.
Pero a través de ldd para enumerar la biblioteca compartida y los productos de archivo para ver la información específica del archivo mymath, encontraremos muchos trucos.
Gcc está vinculado dinámicamente de forma predeterminada, pero ¿qué sucede si no proporcionamos bibliotecas dinámicas y solo proporcionamos bibliotecas estáticas de gcc? Y sabemos que la formación de un programa ejecutable puede no depender solo de una biblioteca, por lo que si vincula 100 bibliotecas, 70 bibliotecas estáticas y 30 bibliotecas dinámicas, ¿cómo debería vincularse gcc?

inserte la descripción de la imagen aquí

Comando Linux (61) - Comando ldd (reproducido del artículo del blogger csdn Lian Miao Big Carp)

2.
Por lo tanto, el enlace dinámico predeterminado de gcc es solo una opción sugerida, y si es un enlace dinámico o un enlace estático depende de si la biblioteca proporcionada es una biblioteca dinámica o una biblioteca estática .
Si solo se proporcionan bibliotecas dinámicas y no trae opciones, se trata de enlaces dinámicos. Sin embargo, si la opción -static está incluida en la compilación, la compilación y el enlace no tendrán éxito en este momento, se informará un error y no se podrán realizar la compilación y el enlace.
Si solo proporciona una biblioteca estática y no tiene una opción, entonces gcc solo se puede vincular estáticamente. Por supuesto, si trae la opción -static, es una práctica más estándar.
Si tanto las bibliotecas dinámicas como las estáticas se entregan a gcc y compilas con la opción -static en este momento, es un enlace estático. Si no lo tienes, es un enlace dinámico.

3.
Siempre que una de las bibliotecas vinculadas sea una biblioteca dinámica, el último método de vinculación presentado por gcc es un vínculo dinámico.
El programa ejecutable mymath no solo vincula la biblioteca estática libmymath.a escrita por nosotros mismos, sino que también vincula la biblioteca dinámica libc.so.6 del lenguaje C, por lo que el método de enlace final presentado es el enlace dinámico.

2.4 Copie la ruta de la biblioteca a la ruta predeterminada del sistema (la esencia de la instalación es copiar)

1.
Copie la ruta de la biblioteca a la ruta predeterminada del sistema, que es esencialmente la instalación. copiar = instalar

inserte la descripción de la imagen aquí
2.
Aunque hayamos copiado la biblioteca en la ruta predeterminada del sistema, si no especificamos el nombre del archivo de la biblioteca de enlaces en el momento de la compilación, se seguirá informando el mismo error de conexión, la referencia indefinida a la función, el razón por la que dijimos anteriormente, el encabezado El código fuente del archivo le dice al archivo de encabezado específico que se vincule, pero nadie le dice al archivo de la biblioteca, y lo que vinculamos no es la biblioteca estándar, sino una biblioteca de terceros, por lo que al menos el La opción -l debe agregarse al compilar .

inserte la descripción de la imagen aquí

3.
Elimine la ruta de la biblioteca en la ruta predeterminada del sistema, que en realidad se está desinstalando.
No se recomienda copiar el código de prueba escrito por nosotros mismos en la ruta predeterminada del sistema. Las bibliotecas en la ruta predeterminada del sistema se han probado estrictamente y el proceso del sistema, como la versión de lanzamiento, la seguridad y la practicidad del código de prueba escrito por nosotros mismos No es lo suficientemente bueno, así que no lo copie en la ruta predeterminada del sistema.

inserte la descripción de la imagen aquí

6. Biblioteca dinámica y enlace dinámico (gcc -shared genera biblioteca dinámica)

1. Genere código independiente de la posición + archivo .o para formar una biblioteca dinámica (gcc -fPIC -c *.c y gcc -shared -o libxxx.so *.o)

gcc -fPIC -c *.c  ---生成.o文件
gcc -shared -o libmymath.so *.o  ---.o文件进行归档形成动态库

shared: significa generar formato de biblioteca compartida
fPIC: generar código independiente de posición (código independiente de posición)
regla de nombre de biblioteca: libxxx.so

inserte la descripción de la imagen aquí

2. Durante la ejecución del programa, al cargar la biblioteca dinámica, el sistema operativo y el shell no pueden encontrar el archivo de la biblioteca (cuatro soluciones)

1.
Luego, empaquetamos los archivos de la biblioteca y los archivos de encabezado y los colocamos en el directorio mylib. Si lo desea, puede comprimir este directorio y dárselo al usuario de la biblioteca. Después de descargar y descomprimir, el usuario puede obtener los archivos de la biblioteca y los archivos de encabezado. .

inserte la descripción de la imagen aquí
2.
El método de uso de la biblioteca dinámica es muy similar al de la biblioteca estática, y el programa ejecutable mymath se puede generar con las opciones correspondientes al compilar.
Pero cuando ejecutamos este programa, hay un problema: nuestro programa mymath está enlazado dinámicamente, pero el sistema no puede encontrar nuestro archivo de biblioteca dinámica libmymath.so.

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

3.
En tiempo de compilación, gcc conoce la ruta y el nombre del archivo de la biblioteca, pero no tiene nada que ver con gcc cuando el programa se está ejecutando. La biblioteca dinámica se carga durante la ejecución del programa, y ​​durante la ejecución, el sistema operativo y shell no sabe dónde está la biblioteca, porque nuestra biblioteca no está en la ruta del sistema, por lo que el sistema operativo no puede encontrarla .

2.1 Agregue la ruta de la biblioteca a la variable de entorno LD_LIBRARY_PATH (no permanentemente, solo temporalmente)

1.
Durante la ejecución del programa, el shell no solo busca la biblioteca en la ruta predeterminada del sistema, sino también en la variable de entorno LD_LIBRARY_PATH, por lo que siempre que la ruta del archivo de la biblioteca dinámica se agregue a la variable de entorno , el problema puede estar solucionado.

2.
A partir del contenido que muestra ldd, puede ver que el sistema operativo ha encontrado correctamente la ruta del archivo de la biblioteca.

inserte la descripción de la imagen aquí

2.2 Agregue un archivo de configuración en el directorio /etc/ld.so.conf.d/ y llame manualmente a ldconfig para actualizarlo

1.
Pero cuando iniciemos sesión en xshell la próxima vez, la ruta que acabamos de agregar en la variable de entorno desaparecerá automáticamente de forma predeterminada, por lo que cuando iniciemos sesión la próxima vez, mymath no podrá ejecutarse normalmente e informará un error. que el archivo de la biblioteca no se puede encontrar. Si desea que la ruta tenga efecto de forma permanente, debe cambiar el archivo de configuración de la variable de entorno. Este archivo de configuración es muy problemático para cambiar, por lo que la solución de la variable de entorno es más adecuada para pruebas ordinarias, y es temporalmente válido bajo este inicio de sesión.

2.
Primero ingrese /etc/ld.so.conf.d/, puede ver que hay muchos archivos de configuración en el directorio, y la ruta de la biblioteca dinámica se almacena en estos directorios.Si escribimos nuestra propia ruta de biblioteca dinámica a un archivo y coloque este archivo en el directorio /etc/ld.so.conf.d/, y el sistema operativo y el shell pueden encontrar el archivo de la biblioteca.

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí
3.
Después de agregar el archivo de configuración, aún puede ver que el archivo de biblioteca dinámica del programa ejecutable aún falta. De hecho, todavía queda un paso. Necesitamos llamar a ldconfig manualmente, porque hemos instalado un nuevo enlace dinámico. biblioteca Por lo tanto, debe informar al sistema, es decir, actualizarlo, y el programa puede ejecutarse normalmente después de la actualización, y la biblioteca dinámica se puede vincular normalmente durante la ejecución del programa .

inserte la descripción de la imagen aquí

Linux: Introducción al uso de ldconfig (reproducido del artículo de csdn blogger technology explorer)

2.3 Bajo el sistema o la ruta actual, cree un enlace suave del archivo de la biblioteca dinámica

1.
Cuando el programa se está ejecutando, el sistema buscará el archivo de la biblioteca dinámica que debe vincularse en la ruta actual, luego podemos crear un acceso directo al archivo de la biblioteca dinámica a través de un enlace suave, para que el sistema pueda encontrar el archivo de biblioteca dinámica correspondiente a través del acceso directo durante la operación Archivos de biblioteca dinámica.

inserte la descripción de la imagen aquí
2.
Además de establecer un enlace suave en la ruta actual, también podemos establecer un enlace suave en la ruta del sistema, de modo que el sistema operativo también pueda encontrar el archivo de la biblioteca dinámica durante la ejecución del programa.

inserte la descripción de la imagen aquí

2.4 Copie la ruta del archivo de la biblioteca dinámica a la ruta predeterminada del sistema (para decirlo sin rodeos, instale la biblioteca dinámica)

No entraré en detalles sobre esta solución, es relativamente simple, solo necesita copiarla y traer la opción sudo al ejecutar el comando, pero esto no se recomienda, porque nuestra biblioteca dinámica es relativamente fácil de comparar con la biblioteca. de otros sistemas, así que no instale bibliotecas dinámicas indiscriminadamente.

3. Instalar otras bibliotecas de terceros ncurses

[wyn@VM-8-2-centos Use_libraries]$ sudo yum install -y ncurses-devel

1.
Después de instalar la biblioteca ncurses, puede encontrar los archivos de encabezado y los archivos de biblioteca de la biblioteca ncurses descargada en el archivo de encabezado predeterminado del sistema y la ruta del archivo de biblioteca.

inserte la descripción de la imagen aquí
2.
El siguiente es el código de demostración utilizando la biblioteca ncurses. También puede reproducirlo en vim. Al compilar el código, debe indicar el nombre de la biblioteca gcc, de lo contrario, se informará un error de conexión: referencia indefinida a la función.

//test.c
 
#include <string.h>
#include <ncurses.h>
 
int main()
{
    
    
    initscr();
    raw();
    noecho();
    curs_set(0);
 
    const char* c = "Hello, World!";
 
    mvprintw(LINES/2,(COLS-strlen(c))/2,c);
    refresh();
 
    getch();
    endwin();
 
    return 0;
}

El siguiente es el resultado de ejecutar el código de demostración
inserte la descripción de la imagen aquí

Introducción a la instalación de la biblioteca curses ncurses (reproducida del artículo de csdn blogger whatday)

7. Comprensión profunda del proceso de carga de bibliotecas dinámicas y estáticas (direccionamiento absoluto, direccionamiento relativo: fPIC genera código independiente de la posición)

1.
No es necesario cargar la biblioteca estática. Al cargar el programa, es decir, compilar y vincular, el sistema copiará el código de la biblioteca estática en el segmento de código del programa ejecutable, porque no hay pila ni montón. segmento en el programa ejecutable, solo el segmento de código, el segmento de datos (se puede subdividir en segmentos .data y .rodata) y el segmento BSS .
Por lo tanto, en la memoria física, debe haber el código de la biblioteca estática , porque el código de la biblioteca estática se cargará en el espacio de direcciones virtuales de la memoria como parte del programa ejecutable y luego se asignará a la memoria física a través de la tabla de páginas, entonces la memoria física tendrá La dirección del código de la biblioteca estática, tal esquema de carga es un esquema de direccionamiento absoluto

inserte la descripción de la imagen aquí

Programa o - asignación de área de memoria (cinco segmentos) - finalmente lo descubrí (reproducido del artículo de csdn blogger helmsgao)

2.
A diferencia del enlace estático, la biblioteca dinámica solo copia la dirección de desplazamiento de la función de biblioteca utilizada por el programa ejecutable en el programa ejecutable.El esquema de direccionamiento de todas las funciones de biblioteca en la biblioteca dinámica adopta el método de inicio: dirección de desplazamiento para el direccionamiento relativo .
Cuando la CPU ejecuta el código, encuentra que hay una dirección externa en la memoria física. Esta dirección externa es la dirección de desplazamiento de la función en la biblioteca dinámica durante la fase de compilación y enlace. La biblioteca dinámica se carga en la memoria física. (lo que debe cargarse al cargar la biblioteca dinámica), y luego el sistema operativo asignará la ubicación de la biblioteca dinámica en la memoria física al área compartida en el espacio de direcciones virtuales a través de la tabla de páginas, una vez que la biblioteca dinámica esté asignada a Compartida Entonces, la dirección de inicio de esta biblioteca se determina de inmediato . Después de completar el mapeo, ¿no hay un desplazamiento de la función de la biblioteca en el espacio de direcciones virtuales? Luego salte directamente al contexto del espacio de direcciones virtuales, salte al área compartida , y ahora tiene la dirección inicial de la biblioteca y el desplazamiento de la función de biblioteca específica, para que pueda encontrar fácilmente el código binario de la función de biblioteca y ejecutarlo Después de que se complete la ejecución, salte al segmento de código y continúe ejecutando el código restante hacia atrás.

3.
Esto también puede explicar que cuando se generan dinámicamente archivos .o, necesitamos agregar la opción -fPIC a la compilación gcc, que permite que las funciones en la biblioteca dinámica usen el esquema de dirección relativa para el direccionamiento, a fin de completar el tiempo de ejecución del programa posterior El proceso de vinculación dinámica .

4.
Al empaquetar archivos .o, gcc usa la opción -shared para formar un formato específico para la biblioteca dinámica , lo cual es conveniente para que el sistema operativo cargue la biblioteca dinámica en la memoria en forma de biblioteca más adelante. Luego asigne al área compartida a través de la tabla de páginas, se determina la dirección de inicio de la biblioteca, el segmento de código salta al área compartida, toma el desplazamiento de la función de biblioteca y la dirección de inicio, ejecuta el código binario de la función de biblioteca correspondiente y luego salta Volver al segmento de código para ejecutar el código binario restante.

5.
Suponiendo que 100 programas usan bibliotecas estáticas, los 100 procesos involucrados en la rotación de procesos tienen sus propios códigos de biblioteca estática, en lugar de compartirlos entre procesos.
Y si 100 programas usan la biblioteca dinámica, solo se requiere una copia del código de la biblioteca dinámica en la memoria física, y los 100 procesos incluidos en la rotación de procesos solo necesitan compartir una copia de la biblioteca dinámica en la memoria física.

inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/erridjsis/article/details/128797445
Recomendado
Clasificación