쪽지발송 성공
Click here
재능넷 이용방법
재능넷 이용방법 동영상편
가입인사 이벤트
판매 수수료 안내
안전거래 TIP
재능인 인증서 발급안내

🌲 지식인의 숲 🌲

🌳 디자인
🌳 음악/영상
🌳 문서작성
🌳 번역/외국어
🌳 프로그램개발
🌳 마케팅/비즈니스
🌳 생활서비스
🌳 철학
🌳 과학
🌳 수학
🌳 역사
해당 지식과 관련있는 인기재능

30년간 직장 생활을 하고 정년 퇴직을 하였습니다.퇴직 후 재능넷 수행 내용은 쇼핑몰/학원/판매점 등 관리 프로그램 및 데이터 ...

AS규정기본적으로 A/S 는 평생 가능합니다. *. 구매자의 요청으로 수정 및 보완이 필요한 경우 일정 금액의 수고비를 상호 협의하에 요청 할수 있...

안녕하세요!!!고객님이 상상하시는 작업물 그 이상을 작업해 드리려 노력합니다.저는 작업물을 완성하여 고객님에게 보내드리는 것으로 거래 완료...

안녕하세요? 틴라이프 / 코딩몬스터에서 개발자로 활동했던 LCS입니다.구매신청하시기전에 쪽지로  내용 / 기한 (마감시간 / ...

Python 비동기 프로그래밍: 동시성으로 성능 개선하기

2024-10-01 15:06:55

재능넷
조회수 525 댓글수 0

🐍 Python 비동기 프로그래밍: 동시성으로 성능 개선하기 🚀

 

 

안녕, 파이썬 마스터가 되고 싶은 친구들! 오늘은 정말 흥미진진한 주제로 찾아왔어. 바로 Python의 비동기 프로그래밍에 대해 깊이 파헤쳐볼 거야. 😎

혹시 너희 중에 여러 가지 일을 동시에 하는 걸 좋아하는 사람 있어? 예를 들어, 음악 들으면서 숙제하고, 동시에 친구랑 카톡하는 그런 거 말이야. 그렇다면 너희는 이미 '비동기'의 개념을 일상에서 실천하고 있는 거야! 👏

프로그래밍에서도 이런 개념이 적용돼. 특히 Python에서는 이걸 '비동기 프로그래밍'이라고 불러. 오늘은 이 멋진 기술에 대해 친구처럼 재미있게 설명해줄게. 준비됐니? 그럼 시작해보자고! 🚀

💡 알쏭달쏭 Tip: 비동기 프로그래밍은 처음에는 좀 어려워 보일 수 있어. 하지만 걱정 마! 우리가 함께 차근차근 알아가다 보면, 어느새 넌 비동기의 달인이 되어 있을 거야. 그리고 이런 실력은 나중에 재능넷 같은 플랫폼에서 네 재능을 뽐내는 데 큰 도움이 될 거야! 😉

🔄 비동기 프로그래밍이 뭐길래?

자, 비동기 프로그래밍이 뭔지 한번 알아볼까? 쉽게 설명하자면, 비동기 프로그래밍은 여러 작업을 동시에 처리할 수 있게 해주는 마법 같은 기술이야. 😲

예를 들어볼게. 넌 지금 피자 가게에서 일하고 있다고 생각해봐. 손님이 피자를 주문하면, 넌 오븐에 피자를 넣고 15분을 기다려야 해. 그런데 그 15분 동안 가만히 있을 거야? 아니지! 다른 일을 할 수 있잖아. 예를 들어 다른 손님의 주문을 받거나, 테이블을 정리하거나, 음료수를 준비할 수 있어.

이게 바로 비동기 프로그래밍의 핵심이야. 한 작업이 끝나기를 기다리는 동안 다른 작업을 수행할 수 있다는 거지. cool하지 않아? 😎

비동기 프로그래밍 개념도 비동기 프로그래밍 Task 1 Task 2 Task 3 Task 4 동시 실행 효율적인 자원 활용

위의 그림을 보면, 비동기 프로그래밍이 어떻게 작동하는지 한눈에 볼 수 있어. 중앙의 큰 원이 비동기 프로그래밍을 나타내고, 주변의 작은 원들은 각각의 태스크를 의미해. 이 태스크들이 동시에 실행되면서 효율적으로 자원을 활용하는 거지. 멋지지 않아? 🌟

그럼 이제 비동기 프로그래밍이 왜 중요한지 알아볼까?

  • 성능 향상: 여러 작업을 동시에 처리하니까 전체적인 실행 시간이 줄어들어.
  • 리소스 효율성: CPU와 메모리를 더 효율적으로 사용할 수 있어.
  • 반응성 개선: 사용자 인터페이스가 더 부드럽고 반응이 빨라져.
  • 확장성: 더 많은 요청을 동시에 처리할 수 있어 대규모 애플리케이션에 적합해.

이렇게 보니까 비동기 프로그래밍이 얼마나 강력한지 알겠지? 😃

🚨 주의사항: 비동기 프로그래밍이 항상 좋은 것만은 아니야. 때로는 코드가 복잡해질 수 있고, 디버깅도 어려워질 수 있어. 그래서 상황에 맞게 적절히 사용하는 게 중요해!

자, 이제 비동기 프로그래밍의 기본 개념을 알았으니, 다음으로 Python에서 어떻게 이걸 구현하는지 알아볼까? 준비됐니? 그럼 고고! 🚀

🐍 Python에서의 비동기 프로그래밍

자, 이제 Python에서 비동기 프로그래밍을 어떻게 구현하는지 알아볼 차례야. Python은 비동기 프로그래밍을 위해 asyncio라는 멋진 라이브러리를 제공해. 이 라이브러리는 Python 3.4부터 도입됐고, 계속해서 발전하고 있어. 😊

asyncio를 사용하면 코루틴(coroutine)이라는 특별한 함수를 만들 수 있어. 코루틴은 실행 중에 일시 중지되고 나중에 다시 시작될 수 있는 함수야. 이게 바로 비동기 프로그래밍의 핵심이지!

자, 그럼 간단한 예제를 통해 asyncio를 사용해보자.


import asyncio

async def say_hello(name):
    print(f"Hello, {name}!")
    await asyncio.sleep(1)
    print(f"Goodbye, {name}!")

async def main():
    await asyncio.gather(
        say_hello("Alice"),
        say_hello("Bob"),
        say_hello("Charlie")
    )

asyncio.run(main())

이 코드가 어떻게 동작하는지 설명해줄게:

  1. async def로 코루틴 함수를 정의해.
  2. await 키워드는 비동기 작업이 완료될 때까지 기다리라는 의미야.
  3. asyncio.gather()는 여러 코루틴을 동시에 실행해.
  4. asyncio.run()은 비동기 프로그램의 진입점이야.

이 코드를 실행하면, "Hello" 메시지가 거의 동시에 출력되고, 1초 후에 "Goodbye" 메시지가 출력돼. 멋지지 않아? 😎

asyncio 동작 원리 asyncio Event Loop Alice Bob Charlie Concurrent Execution

위 그림은 asyncio의 이벤트 루프가 어떻게 동작하는지를 보여줘. Alice, Bob, Charlie라는 세 개의 태스크가 동시에 실행되고 있어. 이벤트 루프는 이 태스크들을 번갈아가며 실행하면서, 효율적으로 리소스를 사용하고 있지. 😊

💡 Pro Tip: asyncio를 마스터하면, 네트워크 프로그래밍이나 웹 스크래핑 같은 I/O 바운드 작업에서 엄청난 성능 향상을 경험할 수 있어. 이런 실력은 재능넷에서 네 가치를 한층 더 높여줄 거야!

자, 이제 기본적인 asyncio 사용법을 알았으니, 좀 더 복잡한 예제를 살펴볼까? 🤔


import asyncio
import random

async def fetch_data(url):
    print(f"Fetching data from {url}")
    await asyncio.sleep(random.uniform(0.5, 2.0))  # 실제 네트워크 요청을 시뮬레이션
    print(f"Finished fetching data from {url}")
    return f"Data from {url}"

async def process_data(data):
    print(f"Processing {data}")
    await asyncio.sleep(0.5)  # 데이터 처리를 시뮬레이션
    print(f"Finished processing {data}")
    return f"Processed {data}"

async def main():
    urls = ['http://example.com', 'http://example.org', 'http://example.net']
    
    # 데이터 가져오기
    fetch_tasks = [fetch_data(url) for url in urls]
    fetched_data = await asyncio.gather(*fetch_tasks)
    
    # 가져온 데이터 처리하기
    process_tasks = [process_data(data) for data in fetched_data]
    processed_data = await asyncio.gather(*process_tasks)
    
    for result in processed_data:
        print(result)

asyncio.run(main())

이 예제는 웹 스크래핑이나 API 요청을 할 때 비동기 프로그래밍이 얼마나 유용한지 보여줘. 여러 URL에서 동시에 데이터를 가져오고, 그 데이터를 처리하는 거야. 😃

이런 방식으로 프로그래밍하면, 네트워크 지연 시간을 효율적으로 활용할 수 있어. 한 URL에서 데이터를 기다리는 동안 다른 URL의 데이터를 가져올 수 있으니까. 👍

🚨 주의사항: 비동기 프로그래밍을 할 때는 항상 예외 처리에 신경 써야 해. 네트워크 오류나 타임아웃 같은 문제가 발생할 수 있거든. try-except 구문을 적절히 사용하는 것을 잊지 마!

자, 이제 비동기 프로그래밍의 기본을 알게 됐어. 근데 여기서 끝이 아니야. 비동기 프로그래밍에는 더 많은 개념과 테크닉이 있어. 다음 섹션에서 더 깊이 파고들어볼까? 준비됐니? Let's go! 🚀

🧠 비동기 프로그래밍의 고급 개념

자, 이제 비동기 프로그래밍의 더 깊은 부분으로 들어가볼 거야. 준비됐니? 심호흡 한 번 하고... 시작해볼까? 😊

1. 태스크(Task)

태스크는 코루틴을 감싸는 객체야. 코루틴의 실행을 추적하고 관리하는 역할을 해. 태스크를 사용하면 코루틴의 상태를 확인하거나, 취소할 수 있어.


import asyncio

async def my_coroutine():
    print("Coroutine started")
    await asyncio.sleep(1)
    print("Coroutine finished")

async def main():
    task = asyncio.create_task(my_coroutine())
    print(f"Task created: {task}")
    await task
    print(f"Task completed: {task}")

asyncio.run(main())

이 예제에서 asyncio.create_task()를 사용해 코루틴을 태스크로 만들었어. 태스크는 생성되자마자 실행을 시작하지만, await를 사용해 완료될 때까지 기다릴 수 있어.

2. 퓨처(Future)

퓨처는 비동기 연산의 최종 결과를 나타내는 객체야. 태스크는 사실 퓨처의 한 종류라고 볼 수 있어. 퓨처는 아직 완료되지 않은 연산을 표현하는데 사용돼.


import asyncio

async def set_after(fut, delay, value):
    await asyncio.sleep(delay)
    fut.set_result(value)

async def main():
    loop = asyncio.get_running_loop()
    fut = loop.create_future()
    
    loop.create_task(set_after(fut, 1, '... World'))
    
    print('Hello ...')
    print(await fut)

asyncio.run(main())

이 예제에서는 퓨처를 만들고, 나중에 그 결과를 설정해. 메인 코루틴은 퓨처가 완료될 때까지 기다렸다가 결과를 출력해.

3. 이벤트 루프(Event Loop)

이벤트 루프는 비동기 프로그램의 핵심이야. 모든 비동기 작업을 관리하고 실행하는 역할을 해. Python의 asyncio는 기본적으로 단일 스레드 이벤트 루프를 사용해.

이벤트 루프 동작 원리 Event Loop Task 1 Task 2 Task 3 Tasks are executed in a round-robin fashion

위 그림은 이벤트 루프의 동작 원리를 보여줘. 이벤트 루프는 계속해서 돌면서 실행 가능한 태스크를 찾아 실행해. 태스크가 I/O 작업 같은 걸 만나면 잠시 중단하고 다른 태스크로 넘어가. 이렇게 해서 효율적으로 리소스를 사용하는 거지. 😊

4. 동시성과 병렬성

많은 사람들이 동시성(Concurrency)과 병렬성(Parallelism)을 혼동해. 하지만 이 둘은 다른 개념이야.

  • 동시성: 여러 작업을 번갈아가며 실행하는 것. 한 번에 하나의 작업만 진행하지만, 빠르게 전환해서 마치 동시에 실행되는 것처럼 보이게 해.
  • 병렬성: 실제로 여러 작업을 동시에 실행하는 것. 이건 멀티코어 프로세서에서 가능해.

asyncio는 기본적으로 동시성을 제공해. 하지만 Python의 멀티프로세싱과 결합하면 병렬성도 달성할 수 있어.

5. 비동기 컨텍스트 매니저

Python의 with 문처럼, asyncio도 비동기 컨텍스트 매니저를 제공해. 이를 통해 리소스의 획득과 해제를 비동기적으로 관리할 수 있어.


import asyncio

class AsyncContextManager:
    async def __aenter__(self):
        print("Entering the context")
        await asyncio.sleep(1)
        return self

    async def __aexit__(self, exc_type, exc, tb):
        print("Exiting the context")
        await asyncio.sleep(1)

async def main():
    async with AsyncContextManager() as manager:
        print("Inside the context")

asyncio.run(main())

이 예제에서 AsyncContextManager는 비동기 컨텍스트 매니저야. __aenter____aexit__ 메서드를 비동기적으로 정의해서 리소스의 획득과 해제를 비동기적으로 처리할 수 있어.

💡 Pro Tip: 비동기 컨텍스트 매니저는 데이터베이스 연결이나 네트워크 소켓 같은 리소스를 관리할 때 특히 유용해. 재능넷에서 백엔드 개발을 할 때 이런 기술을 사용하면 효율적인 리소스 관리가 가능할 거야!

6. 비동기 이터레이터와 제너레이터

Python의 이터레이터와 제너레이터 개념을 비동기 세계로 확장한 거야. 비동기 이터레이터를 사용하면 대량의 데이터를 비동기적으로 처리할 수 있어.


import asyncio

class AsyncRange:
    def __init__(self, start, stop):
        self.start = start
        self.stop = stop

    def __aiter__(self):
        return self

    async def __anext__(self):
        if self.start >= self.stop:
            raise StopAsyncIteration
        await asyncio.sleep(0.1)  # 각 항목 사이에 약간의 지연을 추가
        self.start += 1
        return self.start - 1

async def main():
    async for i in AsyncRange(0, 5):
        print(i)

asyncio.run(main())

이 예제에서 AsyncRange는 비동기 이터레이터야. __aiter____anext__ 메서드를 구현 해서 비동기적으로 값을 생성하고 있어. 이런 방식으로 대량의 데이터를 효율적으로 처리할 수 있지.

7. 비동기 컴프리헨션과 제너레이터 표현식

Python의 리스트 컴프리헨션과 제너레이터 표현식에 익숙하지? asyncio는 이런 편리한 문법을 비동기 세계로 가져왔어.


import asyncio

async def fetch_data(url):
    await asyncio.sleep(1)  # 네트워크 요청을 시뮬레이션
    return f"Data from {url}"

async def main():
    urls = ['http://example.com', 'http://example.org', 'http://example.net']
    
    # 비동기 컴프리헨션
    results = [await fetch_data(url) for url in urls]
    print(results)
    
    # 비동기 제너레이터 표현식
    async for result in (fetch_data(url) for url in urls):
        print(result)

asyncio.run(main())

이 예제에서 비동기 컴프리헨션과 제너레이터 표현식을 사용해 여러 URL에서 데이터를 가져오고 있어. 이런 방식으로 코드를 간결하게 유지하면서도 비동기 작업을 수행할 수 있지.

8. 동시성 제어

여러 코루틴이 동시에 실행될 때, 때로는 이들 사이의 실행 순서나 동시 접근을 제어해야 할 필요가 있어. asyncio는 이를 위한 여러 도구를 제공해.

  • Lock: 한 번에 하나의 코루틴만 특정 코드 블록에 접근할 수 있도록 해.
  • Semaphore: 동시에 실행될 수 있는 코루틴의 수를 제한해.
  • Event: 한 코루틴이 다른 코루틴에게 특정 이벤트가 발생했음을 알릴 수 있게 해.
  • Condition: 복잡한 동기화 시나리오를 처리할 수 있게 해.

import asyncio

async def worker(semaphore, name):
    async with semaphore:
        print(f"{name} is working")
        await asyncio.sleep(1)
    print(f"{name} is done")

async def main():
    semaphore = asyncio.Semaphore(2)  # 최대 2개의 작업만 동시 실행
    workers = [asyncio.create_task(worker(semaphore, f"Worker {i}")) for i in range(5)]
    await asyncio.gather(*workers)

asyncio.run(main())

이 예제에서는 세마포어를 사용해 동시에 실행되는 작업의 수를 2개로 제한하고 있어. 이런 방식으로 리소스 사용을 제어하고 과부하를 방지할 수 있지.

동시성 제어 개념도 Concurrency Control Lock Semaphore Event Coordinating Asynchronous Tasks

위 그림은 동시성 제어의 주요 개념들을 보여줘. Lock, Semaphore, Event 등의 도구들이 어떻게 비동기 태스크들을 조율하는지 볼 수 있어. 이런 도구들을 적절히 사용하면 복잡한 비동기 시스템도 안정적으로 관리할 수 있지. 😊

🚨 주의사항: 동시성 제어 도구를 사용할 때는 데드락(deadlock)에 주의해야 해. 여러 개의 락을 사용할 때 특히 조심해야 하지. 항상 동일한 순서로 락을 획득하고 해제하는 것이 좋아.

9. 비동기 스트림

대량의 데이터를 처리할 때, 모든 데이터를 메모리에 한 번에 로드하는 것은 비효율적일 수 있어. 비동기 스트림을 사용하면 데이터를 청크(chunk) 단위로 비동기적으로 처리할 수 있어.


import asyncio

async def data_source():
    for i in range(10):
        await asyncio.sleep(0.5)  # 데이터 생성 시간을 시뮬레이션
        yield f"data {i}"

async def process_stream():
    async for data in data_source():
        print(f"Processing {data}")
        await asyncio.sleep(0.1)  # 데이터 처리 시간을 시뮬레이션

asyncio.run(process_stream())

이 예제에서 data_source 함수는 비동기 제너레이터로, 데이터를 스트림 형태로 생성해. process_stream 함수는 이 스트림을 비동기적으로 처리하고 있어. 이런 방식으로 대용량 데이터를 효율적으로 처리할 수 있지.

10. 비동기 테스팅

비동기 코드를 테스트하는 것은 동기 코드를 테스트하는 것보다 조금 더 복잡할 수 있어. 하지만 Python의 unittest 모듈과 asyncio를 결합하면 효과적으로 비동기 코드를 테스트할 수 있어.


import asyncio
import unittest

async def async_sum(a, b):
    await asyncio.sleep(0.1)  # 비동기 작업을 시뮬레이션
    return a + b

class TestAsyncSum(unittest.TestCase):
    def test_async_sum(self):
        result = asyncio.run(async_sum(1, 2))
        self.assertEqual(result, 3)

    async def async_test_sum(self):
        result = await async_sum(1, 2)
        self.assertEqual(result, 3)

    def test_async_sum_with_loop(self):
        async def run_test():
            return await self.async_test_sum()
        asyncio.run(run_test())

if __name__ == '__main__':
    unittest.main()

이 예제에서는 세 가지 방법으로 비동기 함수를 테스트하고 있어. asyncio.run()을 사용하는 방법, 비동기 테스트 메서드를 정의하는 방법, 그리고 이벤트 루프 내에서 비동기 테스트를 실행하는 방법을 보여주고 있지.

💡 Pro Tip: 비동기 코드를 테스트할 때는 mock 객체를 사용해 외부 의존성(예: 데이터베이스, 네트워크 요청)을 대체하는 것이 좋아. 이렇게 하면 테스트 실행 시간을 줄이고 더 안정적인 테스트를 작성할 수 있어. 재능넷에서 프로젝트를 진행할 때 이런 테스팅 기법을 적용하면 코드의 품질을 크게 높일 수 있을 거야!

자, 이제 우리는 Python의 비동기 프로그래밍에 대해 꽤 깊이 있게 살펴봤어. 이 개념들을 잘 이해하고 적용한다면, 네트워크 프로그래밍, 웹 개발, 데이터 처리 등 다양한 분야에서 훨씬 더 효율적이고 강력한 프로그램을 만들 수 있을 거야. 😊

비동기 프로그래밍은 처음에는 조금 어렵게 느껴질 수 있어. 하지만 계속 연습하고 실제 프로젝트에 적용해 보면, 점점 더 자연스럽게 사용할 수 있게 될 거야. 그리고 그 과정에서 프로그래밍의 새로운 차원을 경험하게 될 거라고 확신해!

여기까지 Python의 비동기 프로그래밍에 대한 깊이 있는 설명이었어. 이 지식을 바탕으로 더 효율적이고 강력한 프로그램을 만들 수 있기를 바라! 화이팅! 🚀🐍

관련 키워드

  • asyncio
  • 코루틴
  • 이벤트 루프
  • 태스크
  • 퓨처
  • 동시성
  • 비동기 컨텍스트 매니저
  • 비동기 이터레이터
  • 동시성 제어
  • 비동기 테스팅

지적 재산권 보호

지적 재산권 보호 고지

  1. 저작권 및 소유권: 본 컨텐츠는 재능넷의 독점 AI 기술로 생성되었으며, 대한민국 저작권법 및 국제 저작권 협약에 의해 보호됩니다.
  2. AI 생성 컨텐츠의 법적 지위: 본 AI 생성 컨텐츠는 재능넷의 지적 창작물로 인정되며, 관련 법규에 따라 저작권 보호를 받습니다.
  3. 사용 제한: 재능넷의 명시적 서면 동의 없이 본 컨텐츠를 복제, 수정, 배포, 또는 상업적으로 활용하는 행위는 엄격히 금지됩니다.
  4. 데이터 수집 금지: 본 컨텐츠에 대한 무단 스크래핑, 크롤링, 및 자동화된 데이터 수집은 법적 제재의 대상이 됩니다.
  5. AI 학습 제한: 재능넷의 AI 생성 컨텐츠를 타 AI 모델 학습에 무단 사용하는 행위는 금지되며, 이는 지적 재산권 침해로 간주됩니다.

재능넷은 최신 AI 기술과 법률에 기반하여 자사의 지적 재산권을 적극적으로 보호하며,
무단 사용 및 침해 행위에 대해 법적 대응을 할 권리를 보유합니다.

© 2024 재능넷 | All rights reserved.

댓글 작성
0/2000

댓글 0개

해당 지식과 관련있는 인기재능

저렴하고 빠르고 추후 유지 관리 비용 등을 고려 하여 최대한 부담없는 프로그램을 만들어 드리겠습니다.프로그램 제작에 관련된 어떤한 문의도 받...

안녕하세요 응용프로그램 경력 15년이상 / 웹프로그램 경력 12년 이상입니다.맡겨주시면 의뢰인이 생각하시는 그대로 만들어 드리도록 노력하겠습...

저희는 국내 명문대학교 컴퓨터교육과에 재학중인 학생으로 이루어진 팀입니다.개발 프로젝트 실력은 물론이고 C언어, JAVA 및 각종 프로그래밍 언...

📚 생성된 총 지식 10,247 개

  • (주)재능넷 | 대표 : 강정수 | 경기도 수원시 영통구 봉영로 1612, 7층 710-09 호 (영통동) | 사업자등록번호 : 131-86-65451
    통신판매업신고 : 2018-수원영통-0307 | 직업정보제공사업 신고번호 : 중부청 2013-4호 | jaenung@jaenung.net

    (주)재능넷의 사전 서면 동의 없이 재능넷사이트의 일체의 정보, 콘텐츠 및 UI등을 상업적 목적으로 전재, 전송, 스크래핑 등 무단 사용할 수 없습니다.
    (주)재능넷은 통신판매중개자로서 재능넷의 거래당사자가 아니며, 판매자가 등록한 상품정보 및 거래에 대해 재능넷은 일체 책임을 지지 않습니다.

    Copyright © 2024 재능넷 Inc. All rights reserved.
ICT Innovation 대상
미래창조과학부장관 표창
서울특별시
공유기업 지정
한국데이터베이스진흥원
콘텐츠 제공서비스 품질인증
대한민국 중소 중견기업
혁신대상 중소기업청장상
인터넷에코어워드
일자리창출 분야 대상
웹어워드코리아
인터넷 서비스분야 우수상
정보통신산업진흥원장
정부유공 표창장
미래창조과학부
ICT지원사업 선정
기술혁신
벤처기업 확인
기술개발
기업부설 연구소 인정
마이크로소프트
BizsPark 스타트업
대한민국 미래경영대상
재능마켓 부문 수상
대한민국 중소기업인 대회
중소기업중앙회장 표창
국회 중소벤처기업위원회
위원장 표창