Concurrency Programming Guide - 1
Introduction
-
동시성(Concurrency)는 동시에(same time) 발생하는 여러가지 것들의 개념 -
멀티 코어 CPU의 확산과각 프로세서의 코어 개수가 증가할 것이라는인식때문에,개발자는코어를 활용 할 수 있는 새로운 방법이필요하다 -
OS X 및 iOS와 같은 운영체제는여러 프로그램을동시에실행 할수 있지만,대부분의 프로그램은백그라운드에서실행되며,연속으로프로세서 시간이필요하지 않는 작업을 수행한다. -
컴퓨터를 계속
사용하고,사용자의 주의를 끄는 것은 현재forground 앱이다. -
앱이수행해야 할작업은많지만,사용 가능한 코어의일부만 사용중인 경우,추가 처리 리소스가낭비된다. -
과거에는앱에 동시성을도입할 때,하나 이상의 추가 쓰레드가 필요했다 하지만쓰레드 코드를작성하는 것은어렵다. -
쓰레드는수동으로관리해야하는하위 수준 도구이다. -
앱의 최적의 쓰레드 수는현재 시스템 부하 및 기본 하드웨어를 기반으로동적으로 변경될 수 있으므로,올바른 쓰레딩 솔루션 구현은 불가능하지 않지만극도로 어려워진다. -
또한
일반적으로쓰레드와 함께 사용되는 동기화 메커니즘은성능 향상을보장하지 않으면서 소프트웨어 설계에 복잡성과 위험을 추가한다. -
OS X와 iOS는 모두전통적으로쓰레드 기반 시스템과 앱에 있는 것 보다,더 비동기적인 동시 태스크 실행 방식을 채택하고 있다. -
직접 쓰레드를 작성하는 대신,앱은 특정 태스크를 정의한 다음,시스템이이를수행하도록 해야한다. -
시스템이 쓰레드를 관리하게 함으로써원시 쓰레드(raw threads)에서는불가능한 수준의 확장성을얻을 수 있다.- 앱 개밸자는 보다 간단하고 효율적인 프로그래밍 모델을 얻을 수 있다
Concurrency and Application Design
비동기식 앱 설계의 기초와 사용자 정의 작업을 비동기적으로 수행하기 위한 기술
용어에 대한 참고사항
-
이 포스트에서는 task, process, thread 라는 용어가 약간 다르게 사용된다
-
task(작업)-> 수행해야 할 추상적인 작업 개념을 나타내기 위해 사용 -
process(프로세스)-> 실행 중인 실행파일(running executable)을 지칭, 여러 쓰레드를 포함 할 수 있다. -
thread(쓰레드)-> 코드 실행을 위한 별도로 실행 경로(path)를 지칭하기 위해 사용
-
-
컴퓨팅 초기에는 컴퓨터가
수행할 수 있는 단위,시간 당 최대 작업량이CPU의 클럭 속도에 의해결정- 용어 : 클럭 속도 또는 클록 주파수는 컴퓨터 프로세서의 동작 속도이다. “초당 사이클”로 측정하며 헤르츠 단위를 사용한다
-
첨단 기술과 프로세서 설계가 더욱
소형화됨에 따라,열(heat) 및 기타 물리적 제약이프로세서의 최대 클럭 속도를 제한하기 시작 -
그래서 칩 제조업체는
칩의 총 성능을 향상시키는다른 방법을모색했다.- 칩 제조업체의
해결책은각 칩의프로세서 코어 수를 늘리는 것이었다.
- 칩 제조업체의
-
코어 수를 늘리면,CPU의 속도를 높이거나칩 크기또는열(heat) 특성을변경하지 않고도 단일 칩에서 초당 더 많은 명령을 실행 할 수 있다.- 유일한 문제는
여분의 코어를 이용하는 방법이었다.
- 유일한 문제는
-
여러개의 코어를활용하려면,여러가지 작업을동시에수행 할수 있는 소프트웨어가 필요하다. -
OS X 또는 iOS와 같은최신 멀티 태스킹 운영체제의 경우,주어진 시간에100개 이상의다른 코어에 프로그램이 실행될 수 있으므로,각 프로그램을 다른 코어에 스케쥴링 할수 있어야 한다. -
이러한
프로그램(여러가지 작업을 동시에 수행 할 수 있는 소프트웨어)의대부분은 시스템 데몬이거나,실제 처리 시간을 거의 소비하지 않는 백그라운드 앱이다,실제로 필요한 것은개별 앱이여분의 코어를 보다효과적으로 사용하는 방법이다.- 용어 : 멀티태스킹 운영 체제에서 데몬(daemon, 발음: 데이먼/’deɪmən/ 또는 디먼 /’dimən)은 사용자가 직접적으로 제어하지 않고, 백그라운드에서 돌면서 여러 작업을 하는 프로그램을 말한다.
-
앱이 여러 코어를 사용하는전통적인 방법은여러 쓰레드를 만드는 것이다-
그러나
코어 수가늘어나면,쓰레드 솔루션에문제가 생긴다 -
가장 큰 문제는쓰레드 된 코드가임의의 수의 코어에맞게 확장되지 않았다는 것
-
-
코어와 프로그램이 잘 돌아갈 것으로기대하는 것 만큼 많은 쓰레드를 생성 할 수 없다. -
알아야 할 것은,
효과적으로사용 할 수 있는 코어의 수는앱 자체에서 계산하기 어려운 수준이다- 비록 숫자를
정확하게 맞춘다고 할지라도, 여전히너무나 많은 쓰레드를 프로그래밍하고,그것들을 효과적으로 운영하고,그것들이 서로 간섭하지 못하게해야한다.
- 비록 숫자를
-
문제를 요약하지먼,
앱이 다양한 컴퓨터 코어들의 수를 이용 할수 있는 방법이 필요하다 -
단일 앱이수행하는 작업량또는변화하는 시스템 조건을수용할수 있도록동적으로 확장할수 있어야 한다 -
솔루션은 이러한코어를활용하는데필요한 작업량을 늘리지 않도록 충분히 감당해야 한다
The Move Away from Threads
-
쓰레드는수년간 사용되어왔으며,계속 사용되고는 있지만확장 가능한 방식으로여러 작업을 실행하는일반적인 문제를 해결하지는 못한다 -
쓰레드를 활용할 경우,확장 가능한 솔루션을구축해야하는부담이전적으로 개발자에게 있다 -
시스템 조건이변경됨에 따라,동적으로해당 수를 생성하고조정할 쓰레드 수를 결정해야 한다 -
앱이 해당 쓰레드를 생성하고
유지보수하는데 드는 비용의 대부분을 떠맡는다. -
동시성(Concurrency)문제를해결하기 위해, OS X와 iOS는쓰레드에 의존하는 대신,비동기 설계 접근 방식을 사용 -
비동기 기능은 운영체제에 여러해 동안 존재해왔으며, 디스크에서 데이터를 읽는 것과 같이오랜시간이 걸릴 수 있는 작업을시작하는데 종종 사용된다. -
비동기 함수는호출 될 때 백그라운드에서 일부 작업을 수행하여실행중인 task를 시작하지만,해당 작업이 실제로 완료되기 전에 반환한다. -
일반적으로 이 작업에는백그라운드 쓰레드를 가져오고,해당 쓰레드에서원하는 task를 시작한 다음,task가 완료될 때,호출자에게 알림을 보내는작업이 포함된다. -
과거에는 원하는 작업에 대해비동기 함수가 존재하지 않는 경우,자체적으로 비동기 함수를 작성하여고유의 쓰레드를 생성해야 했다. -
하지만 이제 OS X와 iOS는
직접 쓰레드를 관리하지 않고도비동기식으로모든 작업을 수행할 수 있도록 해주는기술을 제공한다
GCD (Grand Central Dispatch)
비동기식으로 task를 시작하는 기술 중 하나
-
GCD는 일반적으로자신의 앱에서 쓰는 쓰레드 관리 코드를사용하여해당 코드를 시스템 수준으로이동시킨다. -
실행할 작업을 정의하고,이를 적절한 dispatch queue에 추가하기만 하면 된다 -
GCD는필요한 쓰레드를 생성하고해당 쓰레드에서 실행되도록 작업을스케쥴링한다 -
쓰레드 관리가 이제시스템의 일부이므로GCD는작업 관리및실행에 대한전체적인 접근 방식을제공하여, 전통적인 쓰레드보다더 나은 효율성을 제공한다. -
Operation queues는dispatch queues와 매우유사한Objective-C 객체이다.-
실행 할 작업을정의한 다음,operation queue애 추가하여해당 작업의 스케줄링 및 실행을처리한다 -
GCD와 마찬가지로operation queue는 모든쓰레드 관리를 처리하여시스템에서가능한 한 신속하고 효율적으로작업을실행하도록 한다.
-
Dispatch Queues
-
dispatch queues는사용자 지정 작업을실행하기 위한C기반 매커니즘이다. -
dispatch queues는작업을 순차적으로 또는 동시에 수행하지만,항상 FIFO(first-in, first-out)로 수행한다. -
dispatch queues는 항상큐에 추가된 것과 동일한 순서로 작업을 큐에서 제외하고 시작한다. -
Serial dispatch queues는한번에 하나의 작업만 실행하며해당 task가 완료될 때 까지 기다린 후, 새 task를 시작한다 -
반대로 concurrent dispatch queues는이미 시작된 작업이 완료될 때 까지 기다리지 않고,가능한 많은 작업을 시작한다.
Dispatch queues의 이점(benefits)
-
Dispatch queues는이해하기 쉽고 간단한 인터페이스를 제공 -
Dispatch queues는자동 및 전체적인 thread pool 관리 기능을 제공 -
Dispatch queues는튜닝된 어셈블리의 속도를 제공 -
Dispatch queues는쓰레드 스택이 앱 메모리에 남아있지 않기 때문에 훨씬 효율적이다 -
Dispatch queues는로드중인 커널에 걸리지 않는다 -
Dispatch queues에task(작업)을 비동기적으로전달하면대기열이 교착상태Dead Lock로만들어 지지 않는다 -
Dispatch queues는자원경쟁 하에 우아하게 확장된다. -
Serial dispatch queues는lock 및 기타 동기화 기본 요소에 대한보다 효율적인 대안을 제공.
-
dispatch queue에 보내는 작업은함수 또는 블록 객체 내에 캡슐화 되어야 한다. -
블록객체는 OS X v10.6 및 iOS 4.0에 도입된C언어 기능으로,개념적으로 포인터와 유사하지만몇가지 추가적인 이점이 있다.-
블록을자신만의 어휘 범위에서(own lexical scope)정의하는대신에 일반적으로 다른 함수나 메소드의 다른 변수에 엑세스(접근) 할 수 있도록 다른 기능이나 메소드 내부에 블록을 정의한다 -
블록을 원래 범위 밖으로 이동하여heap으로복사할 수도 있다
-
-
dispatch queue에블록을 보내면,블록이 복사된다. -
이러한 모든 의미는상대적으로 적은 코드로매우 동적인 작업을구현할 수 있게 한다 -
dispatch queue는GCD기술의 일부이며C런타임의 일부이다
모르는 용어나 개념에 대한 부가적인 정리
thread pool

-
병렬 작업 처리가 많아지면 쓰레드 개수가 증가되고 그에 따른 쓰레드 생성과 스케줄링으로 인해 CPU가 바빠져 메모리 사용량이 늘어난다, 따라서 어플리케이션의 성능이 저하된다.
-
갑작스런 병렬작업의 극대화로 인한 쓰레드 증폭을 막으려면 thread pool을 사용해야 한다.
-
thread pool은 작업 처리에 사용되는 쓰레드를 제한된 개수만큰 정해 놓고 작업 Queue에 들어오는 작업들을 하나씩 쓰레드가 맡아 처리한다.
kernel
-
컴퓨터의 커널은 운영체제의 핵심입니다.
-
운영체제의 다른 모든 부분에 여러 기본적인 서비스를 제공합니다.
-
시스템 자원은 제한되어있지만 프로그램은 많기 때문에 커널은 프로그램의 수행상태인 프로세스 간의 보안 접근을 책임지는 소프트웨어입니다.
-
커널이 이러한 프로세스마다 얼마만큼의 자원을 사용해야 하는지 결정해야하는데 이것을 스케줄링이라고 합니다
heap

-
필요에 의해 동적으로 메모리를 할당 할 때 사용
-
할당해야 할 메모리의 크기를 프로그램이 실행되는 동안 결정해야 하는 경우 (Run time 때) 유용하게 사용되는 공간 = 힙 영역
-
사용자의 요구에 맞게 메모리를 할당해 주기 위해서 (런타임에 메모리 크기를 결정하고 싶을 때)
메모리 동적 할당을 통해 힙 영역에 메모리를 할당해야 한다.