Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

221
Visualizações
¿Por qué este código de Python con subprocesos tiene condiciones de carrera?

Este código crea una condición de carrera:

 import threading ITERS = 100000 x = [0] def worker(): for _ in range(ITERS): x[0] += 1 # this line creates a race condition # because it takes a value, increments and then writes # some inrcements can be done together, and lost def main(): x[0] = 0 # you may use `global x` instead of this list trick too t1 = threading.Thread(target=worker) t2 = threading.Thread(target=worker) t1.start() t2.start() t1.join() t2.join() for i in range(5): main() print(f'iteration {i}. expected x = {ITERS*2}, got {x[0]}')

Producción:

 $ python3 test.py iteration 0. expected x = 200000, got 200000 iteration 1. expected x = 200000, got 148115 iteration 2. expected x = 200000, got 155071 iteration 3. expected x = 200000, got 200000 iteration 4. expected x = 200000, got 200000

Versión Python3:

 Python 3.9.7 (default, Sep 10 2021, 14:59:43) [GCC 11.2.0] on linux

Pensé que GIL lo evitaría y no permitiría que dos subprocesos se ejecutaran juntos hasta que hicieran algo relacionado con io o llamaran a una biblioteca C. Al menos esto es lo que puede concluir de los documentos .

Entonces, ¿qué hace realmente GIL y cuándo se ejecutan los subprocesos en paralelo?

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Leyendo mejor los documentos , creo que ahí está la respuesta:

El mecanismo utilizado por el intérprete de CPython para garantizar que solo un subproceso ejecute el código de bytes de Python a la vez . Esto simplifica la implementación de CPython al hacer que el modelo de objetos (incluidos los tipos integrados críticos como dict) sea implícitamente seguro contra el acceso simultáneo. Bloquear todo el intérprete facilita que el intérprete sea multiproceso, a expensas de gran parte del paralelismo que ofrecen las máquinas multiprocesador.

Sin embargo, algunos módulos de extensión, ya sean estándar o de terceros, están diseñados para liberar la GIL cuando se realizan tareas de computación intensiva, como compresión o hash. Además, el GIL siempre se libera al realizar E/S.

No conozco los aspectos internos, pero supongo que cada línea o bloque de este código de bytes se ejecuta solo, y otros subprocesos están esperando (lo que lo hace lento). Pero algunas líneas constan de varios bloques y no son atómicas.

Esto es lo que obtienes si ejecutas dis.dis('x[0] += 1') :

 0 LOAD_NAME 0 (x) 2 LOAD_CONST 0 (0) 4 DUP_TOP_TWO 6 BINARY_SUBSCR 8 LOAD_CONST 1 (1) 10 INPLACE_ADD 12 ROT_THREE 14 STORE_SUBSCR 16 LOAD_CONST 2 (None) 18 RETURN_VALUE

Algunos de estos se ejecutan de manera concurrente y hacen la condición de carrera. Entonces, GIL solo garantiza que las partes internas de estructuras como list o dict no se dañarán.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda