콘텐츠로 건너뛰기
Home » Python » 페이지 5

Python

컨디션을 통한 스레드 동기화 예제

동시성을 다룰 때 여러 스레드가 하나의 자원에 순차적으로 접근하게 하거나, 반대로 특정한 시점에 동시에 작동하도록 하는 등의 상황에 제대로 대응할 수 있도록 락이나 이벤트와 같은 동기화 수단을 사용한다. 컨디션은 컨디션 락이라고도 하는데, 간단히 말하자면 이벤트와 락을 적절히 결합한 것이다. 락이나 R락을 사용하는 경우, 락을 획득한 구간의 코드는 항상 하나의 스레드만 진행할 수 있다. 락을 사용하는 중간에 다른 스레드로 사용 권한을 넘기려 한다면 현재 획득한 락을 해제하여 크리티컬 구간을 끝내야 한다. 그런데, 경우에 따라서는 atomic한 자원을 사용하려는 구간에서 해당 자원이 준비되지 않아 구간 내에서 일시적으로 실행을 중단하고 대기해야 하는 상황이 될 수 있다. 이런 경우에 컨디션 락을 사용한다.

컨디션은 락을 획득한 구간내에서 락을 일시적으로 반환하고 기다리는 역할을 가능하게 한다. 컨디션 락을 기다리는 스레드는 락을 해제하면서 블럭된다. 그러면 같은 컨디션락을 획득하려는 다른 스레드에게 제어권이 넘어가는데, 이러한 스레드 중에 해당 자원을 생성하는 역할을 담당하는 스레드가 있다면 이 생산자 스레드는 자원을 생성한 후, 이벤트와 비슷하게 대기 중인 다른 스레드를 깨워주게 된다. 생산자 스레드가 락을 반환하고 나면 중단됐다가 깨어난 스레드는 락을 다시 획득해서 해당 자원을 독점적으로 사용할 수 있게 된다.

중요한 것은 컨디션락은 락의 한 종류이기 때문에 대기중인 상태에서 깨어난 스레드는 그 즉시 실행을 재개하는 것이 아니라, 해당 락을 선점한 다른 스레드가 (이 스레드가 자신을 깨워주었을 것이다.) 락을 반환한 후 다시 그 락 객체를 획득해야 실행을 재개할 수 있게 된다는 것이다.

더 보기 »컨디션을 통한 스레드 동기화 예제

파이썬 리스트의 인덱스와 슬라이스

리스트의 인덱스는 0부터 시작한다. 사실 많은 프로그래밍 언어에서 배열의 인덱스는 0부터 시작하기 때문에 “맨 첫원소가 0번이고 그 다음은 1번… N번째 원소는 N-1로 참조할 수 있다.”고 외워두면 그리 헷갈리지는 않는다.

그런데 이게 슬라이스 범위 문법에서는 또 헷갈린다. 그 이유는 슬라이스에서 뒤쪽 범위는 포함되지 않기 때문이다. 게다가 파이썬 리스트는 음수 인덱스를 사용해서 뒤에서부터 위치를 지정하는 것도 있다. 자, 첫번째 원소는 0번인데 뒤에서 부터 세면 -1 번부터 시작한다. 그렇다면 -5:-2는 어디서부터 어디까지일까?

더 보기 »파이썬 리스트의 인덱스와 슬라이스

(Python) 그 날짜가 몇 주째인지 계산하기

특정한 년,월,일을 입력 받았을 때 그 날짜가 해당 월의 몇 째 주에 속하는지를 알려주는 함수를 작성해보자. 예를 들어 2020년 4월 27일 월요일은 4월의 5주차에 해당하는 날이다. 2020년 5월 15일은 2주차에 해당하는 날이다. 27, 15일은 각각 7로 나누는 것만으로도 3주나 차이가 나는데, 정확한 계산방법은 무엇일까?

더 보기 »(Python) 그 날짜가 몇 주째인지 계산하기

파이썬 미니포맷(format()) 사용법

우리는 값을 출력할 때 print() 함수를 사용한다. (python2에서 print는 구문이었지만, python3에서는 함수로 바뀌었다.) print() 함수는 전달 받은 인자를 문자열로 변환하여 표준 출력을 통해서 해당 문자열을 내보낸다. 만약 print(1)이라고 하면 정수 객체를 표현하는 문자열인 "1"을 생성하여 이것을 출력하는 것이다.

하지만 경우에 따라서는 출력되는 값이 이런 저런 양념을 넣어야 할 때가 있다. 고정된 폭에 맞추어 출력하거나 숫자값의 경우에는 세자리마다 콤마를 넣거나 소수점 자리수를 한정해야 할 때도 있다. 공학 계산의 결과를 출력할 때에는 유효숫자의 자리수 만큼 값을 표시하기 위한 서식을 적용해야 할 때도 있다.

더 보기 »파이썬 미니포맷(format()) 사용법

(Python) Awaitable에 대해

await 키워드를 통해서 실행이 완료되기 전에 다른 작업으로 전환이 가능한 동작을 모두 대기가능(awaitable)하다고 한다. 대기 가능한 객체 타입에는 코루틴(asycio.corutine), Task, Future가 있다.

코루틴

이 글에서 말하는 코루틴은 yield를 사용하는 전통적 의미의 코루틴이 아닌 asycio 라이브러리 내에 정의된 비동기 코루틴을 의미하며, 이는 async def 키워드를 사용하여 정의한 함수(코루틴 함수)가 리턴하는 객체이다. 아래 예제에서 #1의 코드는 실질적으로 아무일도 하지 않는데, nested()를 실행만 하면 코루틴 객체를 생성만 하고 실행(스케줄링)을 하지 않기 때문이다.

더 보기 »(Python) Awaitable에 대해

Decimal – 보다 정확한 소수점 산술

들어가기 전에 다음과 같은 코드를 보자. 흔히 하는 실수 중에 하나 인데 float 타입 값으로 반복횟수가 제한된 루프를 만드려고 시도하는 것이다.

a, b = 1, 0.1
while a != 0:
  print(a)
  a -= b

하지만 안타깝게도 이 코드는 의도대로 실행되지 않을 것이다. 왜냐하면 1.0 에서 0.1을 열 번 뺀다하더라도 0이 되지 않기 때문이다. 어째서? (실제로 파이썬 쉘에서 1.0 / 10 == 0.1 이고, 0.1 * 10 == 1 이다)

더 보기 »Decimal – 보다 정확한 소수점 산술

예제로 알아보는 argparse 사용법

몇 년 전에 argparse의 사용법을 간단하게 정리한 글을 발행했는데, 우연히 몇 가지 찾아보다 보니 기능설명의 나열만 읽어봐서는 애매한 부분도 많고 원하는 형태로 설정하는 것도 계속 헷갈려서 큰 맘 먹고 총정리 하는 마음으로 새로운 글을 하나 써보기로 마음 먹었다. 오늘은 명령줄 인자를 파싱하는 도구인 argparse를 어떻게 사용하는지, 그리고 몇몇 경우에 있어서 옵션의 동작을 어떻게 설정하는지를 좀 더 자세히 살펴보고자 한다.

더 보기 »예제로 알아보는 argparse 사용법

벡터를 클래스로 표현하기 (Python)

지난 시간에 이어서 간단한 클래스 예제를 통해서 클래스를 작성하고 활용하는 방법을 살펴보도록 하겠다. 그리고 객체가 가지는 추가적인 비밀스런(?) 메소드나 속성에 대해서도 조금 더 알아보겠다.

개인적으로 데이터나 함수를 묶어두는 용도로 굳이 클래스를 써야하는가에 대해서는 회의적인 입장이다. 모든 객체인스턴스는 속성이나 메소드를 참조하기 위해서는 내부적인 lookup 과정을 거치기 때문에 사실상 사전으로 대체하는 것도 무방하다고 생각한다. 그럼에도 불구하고 이번에는 클래스로 정의해두는 것이 훨씬 더 사용성을 높이고 편리하게 사용될 수 있는 케이스에 대해서 접근해보겠다.

더 보기 »벡터를 클래스로 표현하기 (Python)

IJulia 설치방법

IJulia는 Jupyter용 Julia 커널로 Jupyter 노트북에서 julia를 사용할 수 있게 해준다. Julia 패키지를 설치하고 빌드하면 현재 버전의 Julia 커널이 자동으로 설치된다. 이 글은 Julia를 제거한 후에 새 버전으로 재설치하면서 IJulia를 새로 설치하는 과정을 정리한 것이다.

더 보기 »IJulia 설치방법

파이썬은 인터프리터언어입니까?

최근에 많이 보게 되는 질문 중 하나가 ‘파이썬은 인터프리터 언어입니까? 컴파일언어입니까?’라는 것이다. 개인적으로 이 질문은 사람을 참 난감하게 하는데, 어떻게 답해야하나에 앞서 아직까지도 이 개념을 이렇게 잘못 가르치는 교재 혹은 과정이 대부분이라는 점 때문이다. 그럼 인터프리터 언어와 컴파일 언어가 무엇인지 알아보고, 과연 파이썬은 인터프리터 언어인지 생각해보자.

Richard Holloway quote: The wrong question to ask of a myth is ...

참고로, 보통 나는 이 질문에 ‘반만 맞다’고 말하거나 더 이상의 설명이 귀찮은 경우에는 ‘통상 인터프리터 언어라고 합니다.’라고 답한다.

더 보기 »파이썬은 인터프리터언어입니까?