[python] 파이썬 GIL 해제하기

파이썬은 GIL(Global Interpreter Lock)이라는 잠금 매커니즘을 가지고 있습니다. GIL은 한 번에 하나의 스레드만 파이썬 바이트코드를 실행할 수 있게 하는 것으로, 멀티코어 프로세서 시스템에서 병렬 실행을 제한하는 요소로 작용합니다.

GIL이 존재하는 이유

GIL은 CPython 구현에서 발생하는 문제를 해결하기 위해 도입되었습니다. CPython은 메모리 관리를 위해 참조 카운팅 방식을 사용하는데, 이때 GIL이 필요합니다. GIL이 없다면, 동시에 여러 개의 스레드가 참조 카운트를 증가 또는 감소시키는 과정에서 충돌이 발생할 수 있기 때문입니다.

GIL 해제하기

GIL을 완전히 해제하는 것은 CPython에서는 불가능하지만, 이를 해결하기 위한 다양한 방법이 제안되고 있습니다.

  1. multiprocessing 모듈 사용: multiprocessing 모듈을 사용하여 GIL을 우회하고 별도의 프로세스에서 코드를 실행할 수 있습니다.
    from multiprocessing import Pool
    
    def some_function(x):
        # do something
        return result
    
    if __name__ == '__main__':
        with Pool(processes=4) as pool:
            result = pool.map(some_function, some_iterable)
    
  2. C 언어 확장 모듈 사용: CPU 바운드 작업을 수행하는 부분을 C로 작성한 확장 모듈을 사용하여 GIL을 우회할 수 있습니다.
    #include <Python.h>
    
    static PyObject* some_function(PyObject* self, PyObject* args) {
        // do something
        return result;
    }
    
    static PyMethodDef module_methods[] = {
        {"some_function", some_function, METH_VARARGS, "Some function"},
        {NULL, NULL, 0, NULL}
    };
    
    static struct PyModuleDef module_definition = {
        PyModuleDef_HEAD_INIT,
        "module_name",
        "Module description",
        -1,
        module_methods
    };
    
    PyMODINIT_FUNC PyInit_module_name(void) {
        return PyModule_Create(&module_definition);
    }
    

결론

GIL은 멀티코어 시스템에서 파이썬의 병렬 처리를 제한하는 요인이지만, 적절한 방법을 사용하면 이를 우회하거나 해결할 수 있습니다. 프로젝트의 요구사항과 환경에 맞는 해결책을 선택하여 GIL 문제를 극복할 수 있습니다.

참고 자료: