NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    기타 프로그램이 멈추는 유형과 행, 프리징, 데드락의 차이점과 동시성, 가시성 프로그래밍 방법.

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 녹스나 엘디플레이어를 장시간 사용하다보면 프로그램이 멈추는 경우가 종종 발생합니다. 다른 프로그램들도 메모리 문제나 스레드 또는 아직 수정되지 않은 버그로 인해 문제가 될 수 있습니다. 행(Hang)은 프로그램이 멈추는 현상을 말합니다. 그래서, 프리징(Freezing)과 혼용해서 사용하는 경우가 많은데요. 대부분은 행과 데드락으로 구분합니다.

     

    행(Hang)

    행은 프로그램 내부의 잘못된 로직으로 프로세스가 무한 대기 상태로 빠지거나 다른 프로그램과 자원을 공유하다가 문제를 발생시키거나 다양한 방식으로 나타날 수 있습니다. 증상은 프로그램을 사용할 수 없는 상태이며, 프로세스를 강제로 죽이거나 윈도우를 리부팅 해야합니다. 네트워크 또는 리소스 요청, 마샬링, 메모리를 핸들링할 때 발생할 위험이 있습니다.

     

    프리징(Freezing)

    행과 혼용해서 사용하지만, 프리징은 행과 차이점이 있습니다. 프리징은 일시적인 멈춤 현상으로 어떤 조건이 되면 프리징이 풀리거나 시간이 지나면 풀리기도 합니다. 행은 프로세스가 멈춰서 아무것도 할 수 없지만, 프리징은 프로그램은 멈춰있지만, 내부적으로는 어떤 처리를 계속 수행하고 있는 상태입니다. 네트워크의 지연이나 단일 스레드 처리가 지연되는 경우 종종 발생하게 됩니다. 보통 "렉걸렸다"라고 표현하죠. 행은 "먹통됐다"라고 표현합니다. 최근에도 유튜브나 카카오톡을 사용할 수 없었던 일이 발생했는데요. 이럴때도 프로그램(유튜브, 카카오톡같은...)이 '먹통됐다'라고 뉴스 기사가 나오기도 합니다.

     

    데드락(Deadlock)

    데드락은 교착상태를 말합니다. 서비스를 요청하는 여러 프로그램이 순차적으로 처리하지 못하고 누구에게 먼저 할당해야 할지 모르는 상태를 말합니다. 이렇게되면, 서비스나 리소스를 요청한 프로그램중 어디에 우선권을 줄지 알수 없어서 무한 대기상태에 빠지게 됩니다. 프로그래머라도 어떤 분야에서 개발하느냐에 따라 데드락을 만나는 일은 다양하게 나타납니다. 저같은 경우는 대부분 윈도우 리소스나 데이터베이스에서 이런 증상들을 만나게 됩니다.

     

    동시성과 가시성

    관계형 데이터베이스(RDBMS, Oracle, MSSQL등등)를 사용하면 꼭 듣게되는게 동시성, 가시성, 비가시성등등... 여러가지 시스템 용어들을 듣게됩니다. 학원에서 알려주는 내용들이지만, 프로세스나 코어 또는 JVM이나 .NET Framework에서 동작하므로 정확하게 파악해서 조치하기란 쉽지 않은 일입니다. 여러분들도 알다시피 프로세스와 스레드 아키텍쳐를 이해하면 동시성이 왜 발생하는지 알 수 있습니다. 동시성은 하나의 CPU 하나의 코어가 동시에 실행되는것처럼 보이기 위한 방법입니다. 윈도우는 이런 한정된 리소스 자원을 안정적이고 효율적으로 관리하기 위해 프로세스는 하나만(상호배제, Mutual Exclusion) 가지도록 했습니다. 그래서 이 자원을 프로세스가 사용중이면 다른 프로세스는 기다려야(점유와 대기, Hold & Wait) 합니다. 프로세스가 자원을 다 사용하고 해제(Release)하기 전까지 다른 프로세스가 강제로 가져갈 수 없습니다.(비선점, No Preemption) 각각의 프로세스는 순환적으로 대기(Circular Wait, 순환대기)해야 합니다.

     

    가시성은 CPU와 RAM의 아키텍쳐를 이해하면 왜 발생하는지 알 수 있습니다. 자주 발생하는 문제는 아니지만, 하나의 스레드에서 공유 자원(윈도우 리소스나 프로그램의 변수등등)을 수정한 결과가 다른 스레드에서 갱신되지 않는 경우입니다. 예를 들어서, A 스레드가 수행하는 어떤 일의 결과를 B 스레드가 기다리고 있을 수 있습니다. 병렬 프로그래밍을 하다보면 A의 결과에 따라 B가 어떻게 동작할지 결정해야 합니다. 엔지엠 매크로를 예로 들면, 스크립트 2개를 열고 글로벌 변수에 어떤 값을 A 스크립트가 저장합니다. B 스크립트는 이 값의 상태에 따라 어떤 액션으로 이동해야 할지 결정해야 합니다. 멀티 코어 환경에서 각각 다른 코어에 스레드가 할당되면 메모리가 공유되지 않기 때문에 B 스크립트는 결과를 무한 대기하는 상태가 발생할 수 있습니다. 이런 문제를 프로그래밍에서 해결하기 위해 C, C++, Java, C#등등... 대부분의 언어에서 volatile 키워드를 제공합니다.

     

    여기서 여러 스레드가 공유 자원에 동시에 접근하고 변경하려고 하면 데드락이 발생할 수 있습니다. 대부분의 프로그래밍에서는 디버깅 타임에 이 문제를 감지하고 알려줍니다. 하지만, 릴리즈된 후 문제가 발생하면 원인을 찾기가 어려워집니다. 그래서, 멀티 스레딩 환경이라면 공유 자원(변수나 속성, 객체등등)의 동시성 문제를 해결해야 합니다. Java는 synchronized 키워드를 제공하고 C#은 lock을 사용해서 해당 맴버 변수, 속성, 객체에 엑세스하는걸 막아줍니다. synchronized(싱크로나이즈드), lock(락)은 가시성 문제를 해결할 때 사용합니다. 하지만, volatile은 동시성의 문제를 해결하지 못합니다. 또한, 이들은 JVM, .NET Framework의 중간 언어(MSIL, MicroSoft Intermediate Language) 과정에서 최적화되지 않습니다.

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천1 비추천0

    댓글목록

    등록된 댓글이 없습니다.