본문 바로가기
GD's IT Lectures : 기초부터 시리즈/파이썬(Python) 기초부터 ~

[파이썬(PYTHON) : 중급] 동시성과 병렬성

by GDNGY 2023. 5. 11.

8. 동시성과 병렬성

동시성(concurrency)과 병렬성(parallelism)은 컴퓨팅에서 매우 중요한 개념입니다. 이 두 용어는 프로그램이 여러 작업을 어떻게 처리하냐에 따라 다릅니다. 동시성은 여러 작업이 동시에 시작되어 수행되는 것을 의미하며, 병렬성은 여러 작업이 동시에 실행되는 것을 의미합니다.

8.1 멀티스레딩

멀티스레딩은 하나의 프로세스 내에서 여러 개의 스레드가 동시에 작동하는 방식입니다. 이는 여러 작업을 동시에 처리하거나, 또는 사용자와의 상호작용을 유지하면서 백그라운드 작업을 수행하는 등의 목적으로 사용됩니다.

 

8.1.1 스레드 생성 및 관리

Python에서는 'threading' 모듈을 사용하여 스레드를 생성하고 관리할 수 있습니다.

 

8.1.1.1 threading 모듈을 이용한 스레드 생성

Python에서 스레드를 생성하는 방법은 매우 간단합니다. threading 모듈의 Thread 클래스를 사용하여 스레드를 생성할 수 있습니다. Thread 클래스의 첫 번째 인자는 스레드에서 실행할 함수이며, 두 번째 인자는 해당 함수에 전달할 인자들의 튜플입니다.

import threading

# 스레드에서 실행할 함수
def print_numbers():
    for i in range(10):
        print(i)

# 스레드 생성
thread = threading.Thread(target=print_numbers)

# 스레드 시작
thread.start()

# 이 코드는 0부터 9까지 숫자를 출력하는 print_numbers 함수를 별도의 스레드에서 실행합니다.

 

8.1.1.2 스레드의 시작과 종료

스레드를 시작하려면, Thread 객체의 start() 메서드를 호출하면 됩니다. 스레드를 종료하려면 해당 스레드에서 실행되는 함수가 반환하도록 하면 됩니다.

 

8.1.1.3 스레드의 상태 확인

스레드의 상태를 확인하려면, Thread 객체의 is_alive() 메서드를 사용할 수 있습니다. 이 메서드는 스레드가 아직 실행 중이면 True를, 아니면 False를 반환합니다.

import threading
import time

def print_numbers():
    for i in range(10):
        print(i)
        time.sleep(1)

thread = threading.Thread(target=print_numbers)
thread.start()

while thread.is_alive():
    print("Thread is still running")
    time.sleep(0.5)
    
print("Thread has finished")

 

8.1.2 스레드 동기화

스레드 동기화는 여러 스레드가 동시에 데이터나 자원에 접근할 때 발생하는 문제를 방지하기 위한 방법입니다. 이는 일반적으로 락(lock), 세마포어(semaphore), 이벤트(event), 컨디션(condition) 등의 기능을 사용하여 이루어집니다.

 

8.1.2.1 동기화 문제 이해하기

스레드 동기화 문제는 일반적으로 두 가지 주요한 문제, 경쟁 조건(race condition)과 데드락(deadlock)으로 나뉩니다.

  • 경쟁 조건(race condition): 두 개 이상의 스레드가 동시에 공유 데이터에 접근하려고 할 때, 데이터의 최종 상태가 마지막으로 접근한 스레드에 따라 달라지는 상황을 의미합니다.
  • 데드락(deadlock): 두 개 이상의 스레드가 서로 다른 스레드가 소유한 자원을 기다리며 서로가 서로를 기다리는 상황을 의미합니다. 이런 상황에서는 각 스레드가 무한히 대기하게 되므로 프로그램이 정지하게 됩니다.

8.1.2.2 Lock, RLock 객체 활용

Lock 객체는 한 번에 한 스레드만 특정 코드를 실행하도록 하는 동기화 메커니즘입니다. Lock 객체는 acquire 메서드를 통해 잠글 수 있으며, 이 경우 다른 스레드는 해당 Lock 객체가 release 될 때까지 대기하게 됩니다.

 

RLock(Reentrant Lock)는 한 스레드가 동일한 lock을 여러 번 acquire 할 수 있도록 하는 메커니즘입니다.

import threading

# 공유 자원
data = 0
lock = threading.Lock()

# 스레드에서 실행할 함수
def add_data():
    global data
    with lock:  # lock 획득
        new = data + 1
        data = new  # 공유 자원 업데이트

# 스레드 생성 및 시작
threads = [threading.Thread(target=add_data) for _ in range(100)]
for thread in threads:
    thread.start()

# 모든 스레드가 종료될 때까지 대기
for thread in threads:
    thread.join()

print(data)  # 출력: 100

 

8.1.2.3 Condition, Semaphore, Event 객체 활용

Condition 객체, Semaphore 객체, 그리고 Event 객체는 스레드 동기화를 위한 다른 메커니즘을 제공합니다.

  • Condition 객체는 한 스레드가 다른 스레드에게 특정 이벤트가 발생했음을 알리는 데 사용됩니다. Condition 객체는 기본적으로 Lock을 갖고 있으며, 스레드는 Condition 객체를 통해 lock을 acquire하거나 release할 수 있습니다.
  • Semaphore 객체는 동시에 접근할 수 있는 스레드의 수를 제한하는 데 사용됩니다. Semaphore는 내부 카운터를 유지하며, 스레드가 semaphore를 acquire하면 카운터가 감소하고, release하면 카운터가 증가합니다. 카운터가 0이면, 해당 semaphore를 acquire하려는 스레드는 semaphore가 다시 사용 가능해질 때까지(blocked state) 대기합니다.
  • Event 객체는 일종의 플래그로, 이벤트의 발생 여부를 나타내는 데 사용됩니다. Event 객체의 초기 상태는 비설정(False)이며, set 메서드를 호출하여 이벤트를 설정(True)하고, clear 메서드를 호출하여 이벤트를 비설정(False)할 수 있습니다. 스레드는 wait 메서드를 호출하여 이벤트가 설정될 때까지 대기할 수 있습니다.

다음은 Semaphore 객체를 사용하는 간단한 예제입니다:

import threading
import time

# 세마포어 객체 생성. 동시에 수행할 스레드 수를 3으로 설정.
semaphore = threading.Semaphore(3)

def worker(n):
    # 세마포어 획득
    semaphore.acquire()
    print(f"Worker {n} has acquired the semaphore.")
    
    # 긴 작업 수행
    time.sleep(2)
    
    print(f"Worker {n} has released the semaphore.")
    # 세마포어 반환
    semaphore.release()

threads = [threading.Thread(target=worker, args=(i,)) for i in range(10)]

for thread in threads:
    thread.start()

for thread in threads:
    thread.join()

 

이 코드는 10개의 스레드를 생성하되, 세마포어를 통해 동시에 작업을 수행하는 스레드 수를 3개로 제한합니다.

 

반응형

8.2 멀티프로세싱

멀티프로세싱은 여러 개의 프로세스를 동시에 실행하는 것을 의미합니다. 이를 통해 CPU의 여러 코어를 활용하여 작업을 병렬로 처리할 수 있습니다. 파이썬에서는 multiprocessing 모듈을 이용해 멀티프로세싱을 구현할 수 있습니다.

 

8.2.1 프로세스 생성 및 관리

8.2.1.1 multiprocessing 모듈을 이용한 프로세스 생성

multiprocessing 모듈을 이용해 프로세스를 생성하려면, 먼저 Process 클래스의 인스턴스를 만듭니다. Process 클래스의 생성자는 몇 가지 인자를 받는데, 주요한 것은 다음과 같습니다.

  • target: 프로세스에서 실행할 함수
  • args: target 함수에 전달할 인자의 튜플
from multiprocessing import Process

def greet(name):
    print(f"Hello, {name}!")

p = Process(target=greet, args=("Alice",))
p.start()
p.join()

 

8.2.1.2 프로세스의 시작과 종료

프로세스를 시작하려면, Process 인스턴스의 start 메서드를 호출합니다. 이 메서드를 호출하면, 새로운 프로세스가 생성되고 target 함수가 실행됩니다.

 

프로세스가 종료될 때까지 기다리려면, join 메서드를 사용합니다. join 메서드는 호출한 프로세스가 종료될 때까지 현재 프로세스(보통 부모 프로세스)를 블록합니다.

 

8.2.1.3 프로세스 상태 확인

프로세스의 상태를 확인하려면, Process 인스턴스의 is_alive 메서드를 사용합니다. 이 메서드는 프로세스가 아직 실행 중이면 True를, 그렇지 않으면 False를 반환합니다.

print(p.is_alive())

 

8.2.2 프로세스 간 통신

8.2.2.1 Queue와 Pipe를 이용한 통신

프로세스 간에 데이터를 주고받기 위해서는 공유 메모리나 메시지 패싱 기법을 사용해야 합니다. multiprocessing 모듈은 Queue와 Pipe를 제공하여 이를 지원합니다.

from multiprocessing import Process, Queue

def worker(q):
    q.put("Hello from the child process!")

q = Queue()
p = Process(target=worker, args=(q,))
p.start()
message = q.get()
p.join()

print(f"Received message: {message}")

 

8.2.2.2 Value와 Array를 이용한 데이터 공유

multiprocessing 모듈의 Value와 Array 클래스를 이용하면, 여러 프로세스 간에 데이터를 공유할 수 있습니다. 이들은 각각 하나의 값과 배열을 프로세스 간에 안전하게 공유하는 데 사용됩니다.

from multiprocessing import Process, Value, Array

def worker(n, a):
    n.value = 3.141592
    for i in range(len(a)):
        a[i] **= 2  # square each element

num = Value('d', 0.0)
arr = Array('i', range(10))

p = Process(target=worker, args=(num, arr))
p.start()
p.join()

print(num.value)
print(arr[:])

 

위 코드에서 Value와 Array의 첫 번째 인자는 저장될 데이터의 타입을 지정합니다. 'd'는 double precision float를, 'i'는 integer를 의미합니다.

 

이렇게 멀티프로세싱을 활용하면, 여러 프로세스를 동시에 실행하여 CPU의 여러 코어를 최대한 활용할 수 있습니다. 이는 특히 병렬로 처리할 수 있는 작업에 있어서 큰 효과를 발휘합니다. 다만, 프로세스 간 통신이 필요한 경우, 데이터를 공유하는 데 드는 비용이 크므로 주의해야 합니다.

 

 

8.3. 비동기 프로그래밍

비동기 프로그래밍은 코드의 실행 순서가 일정하지 않은 프로그래밍 패러다임을 의미합니다. Python에서는 asyncio 모듈과 async/await 문법을 사용해 비동기 프로그래밍을 할 수 있습니다.

 

8.3.1. async/await 구문 활용

8.3.1.1. async/await 구문의 이해

async def로 선언된 함수는 '코루틴'이라고 부릅니다. 코루틴은 일반 함수와는 다르게, 실행을 중간에 멈추고 다른 작업을 수행한 뒤 다시 돌아와서 이어서 실행할 수 있습니다. 이러한 특성 덕분에, 코루틴은 동시에 여러 작업을 처리하는 데 유용합니다.

 

await 키워드는 코루틴 내에서 다른 코루틴의 실행을 기다릴 때 사용합니다. 이 키워드를 사용하면, 현재 코루틴의 실행을 일시적으로 멈추고 대기하면서, 다른 코루틴이나 작업을 실행할 수 있는 기회를 줍니다.

 

8.3.1.2. 비동기 함수(async def) 작성과 호출

import asyncio

async def hello():
    print('Hello')
    await asyncio.sleep(1)
    print('World')

asyncio.run(hello())

 

위 코드에서 hello는 비동기 함수로, async def로 선언되었습니다. asyncio.sleep(1)은 1초 동안 대기하는 코루틴입니다. await 키워드를 사용하면 이 코루틴의 실행을 기다릴 수 있습니다.

 

8.3.2. 비동기 작업 관리

8.3.2.1. asyncio 모듈의 이해

asyncio는 Python의 비동기 I/O 프레임워크입니다. 이 모듈은 이벤트 루프, 코루틴, 태스크 등 비동기 프로그래밍을 위한 다양한 기능을 제공합니다.

 

8.3.2.2. asyncio의 태스크 관리

import asyncio

async def hello():
    print('Hello')
    await asyncio.sleep(1)
    print('World')

task = asyncio.create_task(hello())

 

위 코드에서 asyncio.create_task() 함수는 코루틴을 태스크로 변환합니다. 태스크는 코루틴을 이벤트 루프에서 실행할 수 있게 만드는 일종의 래퍼입니다.

 

8.3.2.3. asyncio의 이벤트 루프 활용

import asyncio

async def hello():
    print('Hello')
    await asyncio.sleep(1)
    print('World')

# 코루틴 객체 생성
coro = hello()

# 이벤트 루프 객체 생성
loop = asyncio.get_event_loop()

# 이벤트 루프에서 코루틴 실행
loop.run_until_complete(coro)

 

이벤트 루프는 비동기 작업들을 관리하고 실행하는 중심적인 역할을 합니다. 코루틴을 실행하기 위해서는 이벤트 루프에서 실행해야 하며, 이벤트 루프의 run_until_complete() 메서드를 사용하면 코루틴을 실행하고 종료될 때까지 기다릴 수 있습니다.

 

8.4. concurrent.futures 모듈 활용

concurrent.futures 모듈은 멀티스레딩과 멀티프로세싱 작업을 추상화하여 관리할 수 있게 하는 라이브러리입니다. 이 모듈에서 제공하는 Executor 클래스는 비동기 실행을 위한 메서드를 제공하며, Thread를 이용한 ThreadPoolExecutor와 Process를 이용한 ProcessPoolExecutor 클래스가 있습니다.

 

8.4.1. Executor 객체 사용

8.4.1.1. ThreadPoolExecutor 활용

ThreadPoolExecutor는 스레드 풀을 사용하여 호출을 비동기적으로 실행합니다.

import concurrent.futures
import time

def worker(n):
    print(f'Worker {n} 시작')
    time.sleep(1)
    print(f'Worker {n} 종료')
    return n * n

with concurrent.futures.ThreadPoolExecutor() as executor:
    futures = [executor.submit(worker, i) for i in range(5)]

print('Main thread ends')

 

8.4.1.2. ProcessPoolExecutor 활용

ProcessPoolExecutor는 프로세스 풀을 사용하여 호출을 비동기적으로 실행합니다.

import concurrent.futures
import time

def worker(n):
    print(f'Worker {n} 시작')
    time.sleep(1)
    print(f'Worker {n} 종료')
    return n * n

with concurrent.futures.ProcessPoolExecutor() as executor:
    futures = [executor.submit(worker, i) for i in range(5)]

print('Main thread ends')

 

8.4.2. 비동기 작업 결과 처리

8.4.2.1. Future 객체의 이해

Future 객체는 진행 중인 작업을 캡슐화하며, 그 작업의 상태와 결과를 확인할 수 있습니다.

import concurrent.futures
import time

def worker(n):
    print(f'Worker {n} 시작')
    time.sleep(1)
    print(f'Worker {n} 종료')
    return n * n

with concurrent.futures.ThreadPoolExecutor() as executor:
    futures = [executor.submit(worker, i) for i in range(5)]

for future in concurrent.futures.as_completed(futures):
    print(f'작업 결과: {future.result()}')

 

8.4.2.2. callback을 이용한 비동기 작업 결과 처리

Future 객체에는 작업 완료 시 호출되는 콜백 함수를 추가할 수 있습니다.

import concurrent.futures
import time

def worker(n):
    print(f'Worker {n} 시작')
    time.sleep(1)
    print(f'Worker {n} 종료')
    return n * n

def done_callback(future):
    print(f'작업 결과: {future.result()}')

with concurrent.futures.ThreadPoolExecutor() as executor:
    futures = [executor.submit(worker, i) for i in range(5)]
    for future in futures:
        future.add_done_callback(done_callback)

 

8.5. GIL (Global Interpreter Lock) 이해하기

GIL은 파이썬의 CPython 인터프리터가 한 번에 하나의 스레드만 실행하도록 제한하는 메커니즘입니다. 이는 멀티 코어 프로세서에서 병렬 처리를 제한하는 주요 요인 중 하나입니다.

 

8.5.1. GIL의 개념 및 작동 방식

8.5.1.1. GIL의 정의

GIL은 Global Interpreter Lock의 줄임말로, CPython 인터프리터에서 한 번에 하나의 스레드만 파이썬 바이트코드를 실행하도록 제한하는 메커니즘을 의미합니다. 이는 CPython의 메모리 관리가 멀티스레드에 안전하지 않기 때문에 도입되었습니다.

 

8.5.1.2. GIL의 작동 원리

GIL은 모든 파이썬 객체에 대한 액세스를 제어하는 뮤텍스(mutual exclusion)입니다. 스레드가 파이썬 객체에 액세스하려면 먼저 이 GIL을 획득해야 합니다. 이로 인해 한 번에 하나의 스레드만이 실행될 수 있습니다. 파이썬 인터프리터가 일정 시간 간격으로 스레드를 교체하여 실행하므로 여러 스레드가 동시에 실행되는 것처럼 보일 수 있지만, 실제로는 한 번에 하나의 스레드만 실행됩니다. 

 

8.5.2. GIL의 영향 및 우회 방법

8.5.2.1. GIL의 영향 이해하기

GIL의 가장 큰 영향은 멀티 코어 프로세서에서 병렬 처리를 제한한다는 것입니다. CPU 바운드 작업에서는 멀티스레딩이 병렬화를 제공하지 못합니다. I/O 바운드 작업에서는 GIL이 문제가 되지 않을 수 있지만, CPU 집중적인 작업에서는 GIL로 인해 성능이 크게 저하될 수 있습니다.

 

8.5.2.2. 멀티프로세싱, Jython, IronPython 등을 이용한 GIL 우회 방법

GIL 문제를 우회하는 방법 중 하나는 멀티프로세싱을 이용하는 것입니다. 각 프로세스는 독립적인 GIL을 가지므로, 멀티프로세싱을 사용하면 여러 코어에서 병렬 작업을 수행할 수 있습니다.

 

또 다른 방법은 다른 파이썬 인터프리터를 사용하는 것입니다. Jython이나 IronPython은 GIL을 구현하지 않았으므로, 이들 인터프리터를 사용하면 멀티스레딩에서 병렬 처리를 할 수 있습니다. 하지만 이들 인터프리터는 CPython이 지원하는 몇몇 C 확장 모듈을 지원하지 않을 수 있습니다.

 

또한 Cython과 같은 도구를 사용하여 CPU 집중적인 부분을 C 또는 C++로 작성하고, 이 부분을 병렬로 실행할 수 있도록 하는 것도 하나의 방법입니다. 이 경우 해당 부분에서는 GIL을 해제하고 병렬 처리를 수행할 수 있습니다. 

 

마지막으로, 파이썬의 concurrent.futures 라이브러리와 같은 고수준 병렬 처리 라이브러리를 사용하는 것도 GIL 문제를 우회하는 방법 중 하나입니다. 이 라이브러리는 멀티프로세싱을 쉽게 사용할 수 있도록 추상화를 제공합니다.

 

이렇게 다양한 방법으로 GIL을 우회하거나 그 영향을 줄일 수 있지만, 어떤 방법을 선택할지는 개발 환경, 애플리케이션의 요구 사항, 그리고 사용 가능한 자원 등에 따라 달라질 수 있습니다.

 

8.6. 병렬 컴퓨팅과 분산 컴퓨팅 이해

8.6.1. 병렬 컴퓨팅의 개념 및 장점

8.6.1.1. 병렬 컴퓨팅의 정의

병렬 컴퓨팅은 여러 프로세서(또는 한 프로세서 내의 여러 코어)가 동시에 서로 다른 작업을 수행하는 컴퓨팅 방식을 말합니다. 이 방식은 데이터나 작업을 여러 부분으로 분할하고, 각 부분을 동시에 처리함으로써 전체 작업 시간을 단축시키는 데 초점을 맞추고 있습니다.

 

8.6.1.2. 병렬 컴퓨팅의 장점과 사용 사례

병렬 컴퓨팅의 가장 큰 장점은 높은 처리 성능과 효율성입니다. 병렬 컴퓨팅을 이용하면, 한 번에 하나의 작업만 처리할 수 있는 전통적인 시퀀셜(sequential) 컴퓨팅 방식에 비해 빠른 시간 내에 대량의 데이터를 처리하거나 복잡한 연산을 수행할 수 있습니다. 이런 특성으로 인해, 병렬 컴퓨팅은 과학적 계산, 그래픽 처리, 머신 러닝, 데이터 마이닝 등의 분야에서 널리 활용되고 있습니다.

 

8.6.2. 분산 컴퓨팅의 개념 및 장점

8.6.2.1. 분산 컴퓨팅의 정의

분산 컴퓨팅은 여러 대의 컴퓨터(또는 노드)가 네트워크를 통해 연결되어, 하나의 시스템처럼 작동하는 컴퓨팅 방식을 말합니다. 이 방식은 각 노드가 서로 다른 부분의 작업을 동시에 처리함으로써 큰 규모의 작업을 효과적으로 처리하는 데 초점을 맞추고 있습니다.

 

8.6.2.2. 분산 컴퓨팅의 장점과 사용 사례

분산 컴퓨팅의 가장 큰 장점은 확장성(scalability)과 안정성입니다. 분산 컴퓨팅 시스템은 필요에 따라 쉽게 노드를 추가하거나 제거할 수 있으며, 한 노드에 문제가 발생하더라도 다른 노드가 작업을 계속 처리할 수 있기 때문에 안정적인 서비스 제공이 가능합니다. 또한, 분산 컴퓨팅을 이용하면, 한 대의 컴퓨터로는 처리하기 어려운 대규모 데이터 처리나 복잡한 계산 작업을 수행할 수 있습니다.

 

분산 컴퓨팅은 클라우드 컴퓨팅, 빅데이터 분석, 웹 검색 엔진, 분산 데이터베이스 등 다양한 분야에서 활용되고 있습니다. 예를 들어, Google의 검색 엔진은 수백만 대의 컴퓨터를 이용하여 인터넷의 방대한 정보를 효과적으로 처리하고, 사용자의 검색 요청에 대해 빠르게 응답할 수 있습니다. 또한, 분산 컴퓨팅 기술은 블록체인과 같은 분산화된 시스템에서도 핵심적인 역할을 담당하고 있습니다.

 

8.7. Python에서 병렬 컴퓨팅 및 분산 컴퓨팅 활용

Python은 병렬 컴퓨팅과 분산 컴퓨팅을 지원하는 다양한 라이브러리와 모듈을 제공합니다. 병렬 컴퓨팅에는 multiprocessing과 multithreading 모듈이, 분산 컴퓨팅에는 dask와 PySpark 등이 있습니다.

 

8.7.1. multiprocessing, multithreading 모듈을 이용한 병렬 컴퓨팅

Python의 multiprocessing과 multithreading 모듈은 CPU의 여러 코어를 활용하여 병렬 처리를 수행할 수 있게 해 줍니다.

 

8.7.1.1. 병렬 처리를 위한 데이터 분할

데이터를 병렬 처리하기 위해서는 먼저 전체 데이터를 여러 부분으로 분할해야 합니다. 분할된 데이터는 각각 다른 프로세스나 스레드에서 독립적으로 처리됩니다.

import multiprocessing

# 데이터 분할
data = range(100)
num_processes = multiprocessing.cpu_count()  # 사용할 프로세스의 수
chunks = [data[i::num_processes] for i in range(num_processes)]  # 데이터를 프로세스 수만큼 분할

 

위의 코드는 0부터 99까지의 숫자를 포함하는 리스트를 CPU 코어 수만큼 분할하는 예제입니다.

 

8.7.1.2. 병렬 처리를 위한 작업 할당 및 결과 병합

분할된 데이터에 대한 병렬 처리를 진행하고, 그 결과를 병합하는 과정은 다음과 같습니다.

import multiprocessing

# 병렬 처리할 함수 정의
def work(chunk):
    return sum(chunk)

# 프로세스 풀 생성
with multiprocessing.Pool() as pool:
    results = pool.map(work, chunks)  # 병렬 처리

# 결과 병합
total = sum(results)
print(total)

이 코드는 각 분할된 데이터에 대해 합계를 계산하는 병렬 처리를 수행하고, 그 결과를 합쳐서 출력하는 예제입니다.

 

8.7.2. dask, PySpark 등을 이용한 분산 컴퓨팅

Python에서 분산 컴퓨팅을 활용하기 위해 dask나 PySpark 등의 라이브러리를 사용할 수 있습니다. 이들 라이브러리는 여러 대의 컴퓨터에 걸쳐 데이터를 분산 처리할 수 있도록 지원합니다.

 

8.7.2.1. dask를 이용한 분산 데이터 처리

dask는 큰 데이터를 여러 부분으로 나누어 처리하고, 그 결과를 병합하는 기능을 제공합니다. 다음은 dask를 이용한 간단한 예제입니다.

import dask.array as da

# 큰 배열을 생성하고, 이를 여러 부분으로 나누어 처리합니다.
x = da.ones((10000, 10000), chunks=(1000, 1000))
y = x + x.T
z = y.sum(axis=0)

# 계산을 병렬로 수행하고 결과를 얻습니다.
result = z.compute()

 

이 코드는 큰 배열을 생성하고, 이를 더하고, 그 합계를 계산하는 분산 처리를 수행하는 예제입니다.

 

8.7.2.2. PySpark를 이용한 분산 데이터 처리

PySpark는 Apache Spark의 Python 라이브러리로, 대용량 데이터를 처리하는 데 유용합니다. 다음은 PySpark를 이용한 간단한 예제입니다.

from pyspark import SparkContext

sc = SparkContext("local", "First App")

# 데이터 생성
data = range(1, 10001)
distData = sc.parallelize(data)

# 데이터를 분산 처리하여 합계를 계산합니다.
result = distData.reduce(lambda a, b: a + b)
print(result)

 

이 코드는 1부터 10000까지의 숫자를 포함하는 리스트를 분산 처리하여 합계를 계산하는 예제입니다.

 

 

 

 

2023.05.11 - [GD's IT Lectures : 기초부터 시리즈/파이썬(Python) 기초부터 ~] - [파이썬(PYTHON) : 중급] 네트워크 프로그래밍 (계속)

 

[파이썬(PYTHON) : 중급] 네트워크 프로그래밍 (계속)

7. 네트워크 프로그래밍 (계속) 7.5. 멀티스레딩과 소켓 프로그래밍 7.5.1. 멀티스레딩 개념 이해 7.5.1.1. 스레드와 프로세스의 차이 프로세스는 운영체제로부터 자원을 할당받아 독립적으로 실행되

gdngy.tistory.com

 

반응형

댓글