thread(쓰레드)는 프로그램의 실행흐름 입니다. 하나의 프로세스 안에서여러 개의 쓰레드를 만들 수 있습니다. 즉 프로세스가 부여된 자원을 이용해서 같은 프로세스 내에서 여러 쓰레드들 끼리 자원을 공유할 수 있습니다.
지금까지 로컬환경에서 작성한 프로그램들은 최소 하나의 프로세스 단위와 하나의 쓰레드를 가지게 됩니다.
쓰레드는 동시성을 위해서 만들어진 개념입니다. 하나의 프로세스 안에서 두개이상의 쓰레드를 만들게 되면 두개 이상의 쓰레드가 동시에 일을 하게 됩니다.
위의 프로그램은 단일 프로세스의 단일 쓰레드로 일억번 +1을 하는 프로그램입니다. 실행시켜보면 컴퓨터의 성능에 따라 다르지만 테스트 컴퓨터에서는 6 ~ 7초 정도가 나왔고 증가된 숫자의 결과도 일억이 되는 것을 확인할 수 있습니다.
그러면 이제 쓰레드 두개를 만들면 어떻게될까여?
파이썬에서 멀티 쓰레드를 사용하려면 threading모듈을 임포트해서 사용해야합니다. threading모듈의 Thread클래스에 target인자에 쓰레드 함수를 지정해주고 args로 매개변수를 전달합니다.
그럼하나의 쓰레드에서 천만까지 증가시키는 코드를 두개의 쓰레드로 분리해서 사용하면 속도도 분리 될것같은데 속도는 반으로 줄지도 않았고, 5000000씩 각각의 쓰레드에 전달이 되었지만 최종 증가된 숫자를 천만이 안되었습니다. 이유는 자원에 동시에 쓰레드가 접근하였기 때문입니다. 쓰레드는 동시에 접근하면 오류를 발생시킵니다. 그럼 쓰레드를 식당에 하나 밖에 없는 화장실이라고 상상하면 카운터에는 화장실 열쇠가 있는데 그러면 화장실을 이용할 수 있는 사람은 1명입니다. 화장실에 사람이 있는데 또 다른 사람이 화장실을 사용하고 싶으면 열쇠는 1개이기 때문에 기다려야 합니다. 쓰레드도 임계구역 내에서 실행되면 다른 쓰레드는 대기를 하여야 합니다. 근데 동시에 쓰레드가 실행되면 오류가 발생하는 것은 당연합니다. 그렇기에 보시게 되면 위에 shared_number가 천만이 되어야 하는데 더 적을 것을 확인 할 수 있고, 오류가 발생했다는 것도 알 수 있습니다.
해결해보겠습니다.
여기서 말하는 자원은 변수입니다.
저는 Lock객체를 구현하여 해결했습니다. 쓰레드를 한개로 구현하였고 t1과 t2가 쓰레드입니다. t1이 먼저 자원에 접근하면 lock.acquire()를 통해 t1외에 다른 쓰레드가 자원에 접근할 수 없고, 대기상태로 있습니다. 그리고 코드가 실행 된 이후에 lock.release()를 통해 반환하면 대기 중인 쓰레드가 자원에 접근할 수 있게 됩니다
뮤텍스는 공유된 자원의 데이터를 여러 쓰레드가 접근하는 것을 막는 것입니다. 위에서 화장실 예가 뮤텍스의 예라고 보시면 됩니다.