GNU/Linux >> Tutoriales Linux >  >> Linux

¿Errno es seguro para subprocesos?

Sí, es seguro para subprocesos. En Linux, la variable global errno es específica del subproceso. POSIX requiere que errno sea seguro para subprocesos.

Consulte http://www.unix.org/whitepapers/reentrant.html

En POSIX.1, errno se define como una variable global externa. Pero esta definición es inaceptable en un entorno de subprocesos múltiples, porque su uso puede generar resultados no deterministas. El problema es que dos o más subprocesos pueden encontrar errores, lo que hace que se establezca el mismo errno. En estas circunstancias, un subproceso podría terminar comprobando el errno después de que otro subproceso ya lo haya actualizado.

Para eludir el no determinismo resultante, POSIX.1c redefine serrno como un servicio que puede acceder al número de error por subproceso de la siguiente manera (ISO/IEC 9945:1-1996, §2.4):

Algunas funciones pueden proporcionar el número de error en una variable a la que se accede mediante el símbolo errno. El símbolo errno se define al incluir el encabezado, como lo especifica el estándar C... Para cada subproceso de un proceso, el valor de errno no se verá afectado por las llamadas a funciones o las asignaciones a errno por parte de otros subprocesos.

Consulte también http://linux.die.net/man/3/errno

errno es subproceso local; configurarlo en un subproceso no afecta su valor en ningún otro subproceso.


Errno ya no es una variable simple, es algo complejo detrás de escena, específicamente para que sea seguro para subprocesos.

Ver $ man 3 errno :

ERRNO(3)                   Linux Programmer’s Manual                  ERRNO(3)

NAME
       errno - number of last error

SYNOPSIS
       #include <errno.h>

DESCRIPTION

      ...
       errno is defined by the ISO C standard to be  a  modifiable  lvalue  of
       type  int,  and  must not be explicitly declared; errno may be a macro.
       errno is thread-local; setting it in one thread  does  not  affect  its
       value in any other thread.

Podemos verificar dos veces:

$ cat > test.c
#include <errno.h>
f() { g(errno); }
$ cc -E test.c | grep ^f
f() { g((*__errno_location ())); }
$ 

En errno.h, esta variable se declara como extern int errno;

Esto es lo que dice el estándar C:

La macro errno no necesita ser el identificador de un objeto. Podría expandirse a un valor l modificable resultante de una llamada de función (por ejemplo, *errno() ).

Generalmente, errno es una macro que llama a una función que devuelve la dirección del número de error para el hilo actual, luego lo elimina.

Esto es lo que tengo en Linux, en /usr/include/bits/errno.h:

/* Function to get address of global `errno' variable.  */
extern int *__errno_location (void) __THROW __attribute__ ((__const__));

#  if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value.  */
#   define errno (*__errno_location ())
#  endif

Al final, genera este tipo de código:

> cat essai.c
#include <errno.h>

int
main(void)
{
    errno = 0;

    return 0;
}
> gcc -c -Wall -Wextra -pedantic essai.c
> objdump -d -M intel essai.o

essai.o:     file format elf32-i386


Disassembly of section .text:

00000000 <main>:
   0: 55                    push   ebp
   1: 89 e5                 mov    ebp,esp
   3: 83 e4 f0              and    esp,0xfffffff0
   6: e8 fc ff ff ff        call   7 <main+0x7>  ; get address of errno in EAX
   b: c7 00 00 00 00 00     mov    DWORD PTR [eax],0x0  ; store 0 in errno
  11: b8 00 00 00 00        mov    eax,0x0
  16: 89 ec                 mov    esp,ebp
  18: 5d                    pop    ebp
  19: c3                    ret

Linux
  1. ¿Cómo nombrar un hilo en Linux?

  2. WaitForSingleObject y WaitForMultipleObjects equivalente en Linux?

  3. Subprocesos POSIX separados vs. conectables

  4. seguridad de subprocesos de la función strtok

  5. ¿Es seguro bifurcar desde dentro de un hilo?

Cómo imprimir pthread_t

Id. de subproceso frente a identificador de subproceso

Acceder al subproceso local desde otro subproceso

Abrir un hilo de Python en una nueva ventana de consola

¿Imprimir errno como mnemotécnico?

¿Qué sucede cuando un hilo se bifurca?