[ 콜백 함수, lambda, map, filter 함수 ]

  • 콜백함수
  • lambda
  • map
  • filter

 

 

 

 

 

콜백 함수

  • 호출 방향이 반대임.
  • 즉, 사용자 정의 코드에서 함수를 호출하는 것이 아니라 함수에서 사용자 정의 코드를 호출하는 함수
  • 함수를 함수의 인자로 전달받아서 함수에서 인자로 전달받은 함수를 호출하는 것

 

 

lambda 함수

  • 간단한 알고리즘 코드 블록
  • 메모리에 저장 안되므로 간단한 연산에 사용
  • lambda 입력인자목록 : 수행코드(연산식)

 

 

map 함수

  • 순서가 있는 데이터들에 (ex, 리스트) 함수의 결과를 적용시키기 위해 사용

 

 

filter 함수

  • return 값이 True or False (<-- map 함수와의 차이)

 

# callback
def square(val):
    return val ** 2

def caller(func, val):
    if type(val) != str:
        return func(val)
    else:
        return 'val Error'
    
    
print(caller(square, 2))
print(caller(square, '2'))


# lambda 
res = lambda a, b : a+b


# map()
ls = list(range(10))

def even(i):
    if i % 2 == 0:
        return 'even'
    else:
        return 'odd'

print(list(map(even, ls)))

# map 없이 사용
result = []
for i in ls:
    if i % 2 == 0:
        result.append('even')
    else:
        result.append('odd')
print(result)


# filter() - return 값이 True or False (map 함수와의 차이)
ls = list(range(10))

def even(i):
    if i % 2 == 0:
        return True
    else:
        return False

print(list(filter(even, ls)))

'Python' 카테고리의 다른 글

[ Thread ] 스레드 (3) - Lock()  (0) 2022.12.16
[ Thread ] 스레드 (2) - 멀티 스레드  (0) 2022.12.15
[ Thread ] 스레드 (1)  (0) 2022.12.14
[Socket] 소켓(Socket) 프로그래밍 (1)  (1) 2022.09.21
[Python] enumerate 함수  (0) 2022.01.26

스레드 (3)

  • Lock
  • global 

 

 

Lock 

  • Lock은 python threading패키지에서 지원
  • Lock을 acquire하면 해당 쓰레드만 공유 데이터에 접근할 수 있고, lock을 release 해야만
    다른 쓰레드에서 공유 데이터에 접근할 수 있음
  • 아래 코드에서 2개의 스레드로 글로벌 변수로 사용해 연산을 하면, 1억이 아닌 다른 값이 나옴
    • 같은 변수를 동시에 접근하기 때문에 발생 --> 이를 위해서 Lock 함수가 사용됨
# thread lock()
import time
import threading


shared_num = 0

def thread_func1(num):
    global shared_num
    for i in range(num):
        shared_num += 1

def thread_func2(num):
    global shared_num
    for i in range(num):
        shared_num += 1

if __name__ == "__main__":
    
    increased_num = 0
    
    start = time.time()
    
    # for i in range(100000000):
    #     increased_num += 1
    
    threads = []
    t1 = threading.Thread(target=thread_func1, args=(50000000, ))
    t1.start()
    threads.append(t1)

    t2 = threading.Thread(target=thread_func2, args=(50000000, ))
    t2.start()
    threads.append(t2)
    
    
    for t in threads:
        t.join()
    
    print(f'shared number : {shared_num}')

    end = time.time() - start
    print(end)
  • 아래 그림과 같이 Lock 해주면 연산결과가 제대로 나옴
shared_num = 0
lock = threading.Lock()     # lock()

def thread_func1(num):
    global shared_num
    
    lock.acquire()          # 다른 쓰레드가 공유 데이터 접근 금지
    for i in range(num):
        shared_num += 1
    lock.release()          # lock 해제

def thread_func2(num):
    global shared_num
    
    lock.acquire()          # 다른 쓰레드가 공유 데이터 접근 금지
    for i in range(num):
        shared_num += 1
    lock.release()          # lock 해제

 

Global

  • 위 코드에서 전역변수에 대해 함수 내에서 사용하기 위해서는 global 변수명으로 선언하면 사용할 수 있음.

 

Reference 

 

[Python] Thread and Lock (쓰레드와 락)

쓰레드(Thread)는 프로그램의 실행 흐름입니다. 하나의 프로세스 안에서 여러 개의 쓰레드를 만들 수 있습니다. 프로세스란 말은 메모리에 할당되어 있는 한 개의 프로그램을 의미하고, 프로그램

velog.io

 

 

스레드 (2) - 멀티 스레드

  • GIL (Global Interpreter Lock)
  • 멀티 프로세싱 (multi-processing)
  • 스레드 vs 프로세스

 

 

GIL (Global Interpreter Lock)

  • 파이썬에서는 하나의 프로세스 안에 모든 자원의 락(Lock)을 글로벌하게 관리함으로써 하나의 쓰레드만 자원을 컨트롤하여 동작하도록 함
  • 아래 그림에서 스레드 하나 실행 시간은 약 0.1초, 두 개 실행 실행시키면 0.2초가 나옴
    • GIL 때문, 즉 한번에 하나의 스레드만 실행 시킴
    • 두 개의 thread를 사용해서 0.1가 나오기 위해서는 멀티 프로세싱을 사용해야함.
import threading
import time 


def thread_func(num):
    for i in range(num):
        pass

def thread_func1(num):
    for i in range(num):
        pass


# # multi thread
# start_time = time.time()

# t = threading.Thread(target=thread_func, args=(10000000, ))        
# t2 = threading.Thread(target=thread_func1, args=(10000000, ))        

# t.start()
# t2.start()

# t.join()
# t2.join()

# end_time = time.time() - start_time
# print(f'elapsed time : {end_time}')

 

멀티 프로세싱 (multi-processing)

  • threading 모듈과 구현방식이 유사
  •  단점
    • 프로세스는 각자의 고유한 메모리 영역을 가지고 있기 때문에 스레드에 비해 메모리 사용량이 늘어남
  • 아래 코드의 경우, 프로세스 1개 실행 시, 0.16초, 2개 실행 시, 0.17초 정도로 동시에 실행되는 것을 확인할 수 있음
import threading
import multiprocessing as mp
import time 


def thread_func(num):
    for i in range(num):
        pass

def thread_func1(num):
    for i in range(num):
        pass

  

if __name__ == '__main__':
    start_time = time.time()

    # multi processing
    m1 = mp.Process(target=thread_func, args=(10000000, ))
    m2 = mp.Process(target=thread_func1, args=(10000000, ))
    
    m1.start()
    m2.start()
    
    m1.join()
    m2.join()


    end_time = time.time() - start_time
    print(f'elapsed time : {end_time}')

 

 

스레드 vs 프로세스

  • 파이썬에서 병렬처리를 구현하는 방식은 멀티스레드 or 멀티프로세스 방식이 있음
  • 스레드의 경우, 
    • GIL로 계산 처리 작업은 하나의 스레드에서만 작동하여 CPU 작업이 적고, I/O 작업이 많은 병렬처리에 효과적
  • 프로세스의 경우,
    • 각자가 고유한 메모리 영역을 가지므로 메모리 사용이 많음
    • 각각의 프로세스에서 병렬로 cpu 작업을 할 수 있어 여러 머신에서 동작하는 분산 처리 프로그램 구현이 가능함

 

Reference

 

Nathan's Blog

The blog to learn more.

monkey3199.github.io

 

 

 

 

'Python' 카테고리의 다른 글

[ Python ] 콜백함수, lambda, map, filter 함수  (0) 2023.01.02
[ Thread ] 스레드 (3) - Lock()  (0) 2022.12.16
[ Thread ] 스레드 (1)  (0) 2022.12.14
[Socket] 소켓(Socket) 프로그래밍 (1)  (1) 2022.09.21
[Python] enumerate 함수  (0) 2022.01.26

스레드 (1)

  • 개념 정의
  • 파이썬 스레드
  • 데몬 스레드
  • fork, join

 

개념 정의

  • 운영체제는 동시에 실행되는 여러 프로그램들을 잘 관리해야한느데 이런 작업을 스케줄링 이라함
  • 스케줄의 단위는 스레드인데, 프로그램은 여러개의 스레드를 사용할 수 있는데, 이를 멀티 스레드라고 함
  •  스레드
    • 프로세스의 실행 단위
  • 프로세스 
    • 프로그램이 메모리에 올라가서 실행 중인 것을 말함

 

 

파이썬 스레드

  • thread, threading 모듈이 있음 <-- threding 모듈을 더 많이 사용함
  • GUI 라이브러리인 QThread 도 있음
  • run 메소드
    • start 함수 실행하면 클래스 안에 run 함수가 호출됨
  • start 메소드
    • 쓰레드 실행하는 함수
  • join 메소드
    • 쓰레드가 종료될 때까지 대기함
import threading
import time


# thread 직접 사용
def t_Thread(num1, num2):
    for i in range(5):
        print(f'thread : {i}')
        time.sleep(1)

t = threading.Thread(target=t_Thread, args=(1, 10))   # target=thread func name, args=(num1, num2)
t.start()
print('Main Thread')



# class 사용
class Worker(threading.Thread):
    def __init__(self, num):
        super().__init__()
        self.num = num        

    def run(self):  
        for i in range(self.num):
            print(f'sub thread start {i}\n')
            time.sleep(1)



if __name__ == '__main__':

    print('main thread start')    

    t = Worker(5)                        # thread 생성
    t.daemon = True                     # 데몬 스레드 실행 --> 프
    t.start()                           # sub thread run() 호출됨

    print('main thread end ')

 

 

데몬 스레드

  • 데몬 속성 - 서브 쓰레드가 데몬 쓰레드인지 아닌지를 지정하는 것 (디폴트 False)
  • 데몬 스레드 - 백그라운드에서 실행되는 스레드로 메인 쓰레드가 종료되면 즉시 종료되는 스레드
  • 데몬 스레드가 아니면 해당 서브 쓰레드는 메인 스레드가 종료되도 자기 작업이 끝날때까지 지속됨
  • GUI 라이브러리인 QThread 도 있음
# 데몬 스레드(daemon thread)

import threading
import time

def count(num, t, thread_num):
    print(f'thread {thread_num} start')
    
    for i in range(num):
        print(f'thread {thread_num} running {i}')
        time.sleep(t)
    
    print(f'thread {thread_num} ends')

thread_1 = threading.Thread(target=count, args=(10, 0.5, 1))
thread_1.daemon = True  # default : False
thread_1.start()

count(5, 0.5, 2)

 

 

Fork, Join 함수

  • Fork
    • 메인 스레드가 서브 스레드를 생성하는 것
    • 두개의 서브 스레드를 생성하는 경우, 메인스레드를 포함하여 총 3개의 스레드가 스케줄링 됨
  • Join
    • join 은 모든 스레드가 작업을 마칠때 까지 기다리는 것을 의미함. 
    • 데이터를 여러 스레드를 통해서 별렬로 처리한 후 그 값들을 다시 모아서 순차적으로 처리해야 할 필요가 있을때, 분할한 데이터가 모든 스레드에서  처리 될 때까지 기다렸다가 메인 스레드가 다시 추후 작업을 하는 경우에 사용
    • 부모 스레드, 즉, 해당 스레드를 생성한 스레드를 진행하지 않고, 자식 스레드 즉 새로 생성한 스레드의 종료를 기다려 준다는 의미
    • 스레드가 끝날때 까지 기다려 주는 함수

import threading
import time


class Worker(threading.Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name    # thread 이름 지정
        
    def run(self):
        print('sub thread start', threading.current_thread().getName())
        time.sleep(5)
        print('sub thread start', threading.current_thread().getName())
        


print('main thread start')

t1 = Worker('1')    # sub thread 생성
t1.start()          # sub thread run method 호출

t2 = Worker('2')    # sub thread 생성
t2.start()          # sub thread run method 호출

t1.join()
t2.join()

print('main thread post job')
print('main thread end')


"""
# thread 여러개 생성
print('main thread start')

threads = []
for i in range(3):
	thread = Worker(i)
    thread.start()
    threads.append(thread)
    

for thread in threads:
	thread.join()

print('main thread post job')
print('main thread end')

"""

 

 

 

reference

 

02) 파이썬 스레드

[TOC] ## 프로세스와 스레드 운영체제에서 어떤 실행 프로그램이 실행된다는 것은 CPU, 메모리, SSD와 같은 컴퓨터 자원을 사용합니다. 따라서 운영체체제는 프로그램들이…

wikidocs.net

 

Python Thread 예제

파이썬에서 스레드를 사용하는 방법을 다루고 있습니다. 1. 쓰레드 (Thread) 2. 스레드 생성 및 실행 3. join 함수 4. 데몬 쓰레드 5. Concurrent.futures 모듈 6. 전역 변수 공유 7. GIL(Global Interpreter Lock) 8. 프

webnautes.tistory.com

 

 

[edu] thread start/join (스레드 시작, 조인, start, join)

프로그램을 작성하다 보면 동시성이 필요하게 될때가 있다. 즉 여러가지 일을 동시에 진행해야 한다. os 에서 프로세스마다 리소스를 할당해서 여러 프로세스가 동시에 실행되는데 하나의 프로

burningrizen.tistory.com

 

'Python' 카테고리의 다른 글

[ Thread ] 스레드 (3) - Lock()  (0) 2022.12.16
[ Thread ] 스레드 (2) - 멀티 스레드  (0) 2022.12.15
[Socket] 소켓(Socket) 프로그래밍 (1)  (1) 2022.09.21
[Python] enumerate 함수  (0) 2022.01.26
[Python] Zip 함수  (0) 2022.01.26

[Socket] 소켓(Socket) 프로그래밍 (1)

 - 소켓 프로그래밍 개요

 - 구조체 파일 전송 방법 - Struct

    . Big Endian vs Little Endian

 - 프로토콜 설계

 

 

 

 

소켓(Socket) 프로그래밍 개요

 - 다른 디바이간 데이터를 주고받기 위한 프로그래밍.

 - 네트워크 프로그래밍

 - TCP/IP 소켓 프로그래밍 개념도

TCP/IP 소켓 프로그래밍 개념

 - 자세한 내용은 아래 블로그 참조

https://velog.io/@devsh/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EC%B4%88-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC%ED%95%98%EA%B8%B0-%EC%86%8C%EC%BC%93%EA%B3%BC-%EC%86%8C%EC%BC%93-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EA%B0%9C%EB%85%90

 

네트워크 기초 개념 정리하기 - 소켓과 소켓 프로그래밍 개념

소켓은 사전적인 의미로 구멍, 연결, 콘센트등의 의미한다.. 이와 마찬가지로 네트워크 프로그래밍 관전에서도 소켓의 의미는 프로그램이 네트워크에서 데이터를 송수신할 수 있도록 "네트워크

velog.io

 

 

 

 

구조체 파일 전송 방법 - Struct 

 - 샘플 코드가 아닌 실제 데이터 전송을 위해서는 구조체 형태의 파일이 일반적임.

 - 파이썬에서 구조체 형태로 변형을 위해서 struct 모듈 제공. 

 - 이외에도 pickle, shelve 등이 있음 <-- 추후 스터디.

 - 아래 그림은 struct 모듈에서 제공하는 포맷 스트링

 - 자세한 내용은 아래 참조 

https://docs.python.org/3/library/struct.html

 

struct — Interpret bytes as packed binary data — Python 3.10.7 documentation

struct — Interpret bytes as packed binary data Source code: Lib/struct.py This module performs conversions between Python values and C structs represented as Python bytes objects. This can be used in handling binary data stored in files or from network c

docs.python.org

 

 

- pack, unpack, calcsize

  • pack
    • 여러가지 타입의 데이터들을 구조체 형식으로 변환
  • unpack
    • pack 된 데이터를 튜플로 반환
  • calcsize
    • 파이썬 문자열이 요구하는 바이트 반환

 

 

 

 

Big Endian vs Little Endian

 - 바이트 배치 순서에 따라 big endian, little endian 으로 구분됨

 - 구조체 형태로 pack 할때, big endian, little endian 구분해서 할 수 있음.

 - 서로 다른 기기에 맞춰서 셋팅해줘야함.

 

 - 자세한 설명은 아래 참조

https://jhnyang.tistory.com/172

 

[Byte Order 바이트 오더] 빅엔디안(Big Endian)과 리틀엔디안(little endian) - 1편

안녕하세요~~!! 오늘도 시작되는 말랑이몰랑이 블로그 포스팅입니다~ ㅎㅎ 오늘은 네트워크나 통신쪽을 공부한다면 알고 있어야 할 Byte Order 의 빅엔디안과 리틀엔디안에 대한 개념을 완전하게

jhnyang.tistory.com

 

 

 

 

 

- sample code - pack, unpack, calcsize

    # pack 
    pack_1 = pack('!hhl', 1, 2, 3)
    print(f'pack_1 : {pack("!hhl", 1, 2, 3)}')
    
    # unpack
    unpack_1 = unpack('!hhl', pack_1)
    print(f'unpack_1 : {unpack_1}')
    
    # calsize
    print(f'size : !hhl : {calcsize("!hhl")}')
    
    
    # pack
    pack_2 = pack('>3h', 1, 2, 3)
    print(f'pakc_2 : {pack(">3h", 1, 2, 3)}')
    
    # unpack
    unpack_2 = unpack('>3h', pack_2)
    print(f'unpack_2 : {unpack_2}')
    
    
    
    # pack
    pack_3 = pack('<6s', bytes("hello", "utf-8"))
    print(pack('<6s', bytes("hello", "utf-8")))
    
    # unpack
    unpack_3 = unpack('<6s', pack_3)
    print(unpack_3)
    
    
    
    
    print(f'Done..')

 

 

 

Reference 

https://plummmm.tistory.com/176

 

파이썬 struct 모듈 (pack, unpack)

 파이썬 자료형과 c언어 구조체형 사이에서 데이터 변환을 할 때 사용하는 것이다. 이 친구들은 당연히 import struct 를 해줘야 사용이 가능하지. C 프로그램이 파일에 저장한 바이너리 정보들을

plummmm.tistory.com

 

 

 

'Python' 카테고리의 다른 글

[ Thread ] 스레드 (2) - 멀티 스레드  (0) 2022.12.15
[ Thread ] 스레드 (1)  (0) 2022.12.14
[Python] enumerate 함수  (0) 2022.01.26
[Python] Zip 함수  (0) 2022.01.26
[Python] lambda (람다 함수), map 함수, reduce 함수  (0) 2022.01.25

enumerate 함수

 - 순서가 있는 자료형 (리스트, 튜플, 문자열)을 입력 받아 인덱스 값을 포함하는 객체를 돌려줌

 

>> for i, name in enumerate(['t1', 't2', 't3', 't4']):
>>     print(i, name)
    
    
>> 0 t1
>> 1 t2
>> 2 t3
>> 3 t4

'Python' 카테고리의 다른 글

[ Thread ] 스레드 (1)  (0) 2022.12.14
[Socket] 소켓(Socket) 프로그래밍 (1)  (1) 2022.09.21
[Python] Zip 함수  (0) 2022.01.26
[Python] lambda (람다 함수), map 함수, reduce 함수  (0) 2022.01.25
[Python] find , rfind 함수  (0) 2022.01.24

Zip 함수 

 - 동일한 개수로 이루어진 자료형을 묶어주는 역할을 하는 내장 함수

 

>> for num, upper, lower in zip('12345', 'ABCDE', 'abcde'):
>> 	print(num, upper, lower)
>>
>> 1 A a
>> 2 B b
>> 3 C c
>> 4 D d
>> 5 E e

'Python' 카테고리의 다른 글

[ Thread ] 스레드 (1)  (0) 2022.12.14
[Socket] 소켓(Socket) 프로그래밍 (1)  (1) 2022.09.21
[Python] enumerate 함수  (0) 2022.01.26
[Python] lambda (람다 함수), map 함수, reduce 함수  (0) 2022.01.25
[Python] find , rfind 함수  (0) 2022.01.24

lambda (람다 함수)

 - lambda 매개변수 : 표현식

 

>> add = lambda x,y : x+y
>> print(add(10, 20))
>> 30

 

map 함수

 - map(함수, 리스트)

 - 리스트 원소를 하나씩 꺼내 함수에 적용 후, 새로운 리스트 생성

>> test_list = list(map(lambda x:x*2, range(5)))
>> print(test_list)
>> [0, 2, 4, 6, 8]

 

 

reduce 함수

 - reduce (함수, 시퀀스)

 - 시퀀스(문자열, 리스트, 튜플) 원소들을 누적하여 함수에 적용

>> from functools import reduce 
>> 
>> print(reduce(lambda x, y: x + y, [0, 1, 2, 3]))
>> 6
>>
>> print(reduce(lambda x, y: x + y, [0, 1, 2, 3, 4]))
>> 
>> 10

 

'Python' 카테고리의 다른 글

[ Thread ] 스레드 (1)  (0) 2022.12.14
[Socket] 소켓(Socket) 프로그래밍 (1)  (1) 2022.09.21
[Python] enumerate 함수  (0) 2022.01.26
[Python] Zip 함수  (0) 2022.01.26
[Python] find , rfind 함수  (0) 2022.01.24

+ Recent posts