고수가 되는 파이썬 : 동시성과 병렬성 문법 배우기 Feat. 멀티스레딩 vs 멀티프로세싱 (Inflearn Original)
안녕하세요, 강사님. 항상 좋은강의에 감사드립니다. 섹션2을 다 듣고나서, 스스로 정리를 하고 궁금한 부분들을 한번에 질문드립니다. 제가 컴퓨터쪽 전공이 아니라서 용어나 잘 모르는 부분이 많아 질문이 깔끔하지 않은점 이해 부탁드립니다. (섹션1도 다 듣고 동일한 방법으로 질문을 최근에 해서... 혹시 게시판에 도배가 되지 않을까 실례됩니다. 너무 질문이 잦다면 말씀주세요!) 그리고 제 질문들이 당연한것일수도 있는데... 강사님께 한번 더 확인(?)을 받으면 더 효율적으로 이해가되서 문의드립니다^^! 질문이 많고 clear하지 않음에 다시한번 양해를 부탁드리며, 미리 답변에 진심으로 감사드립니다. 0. thread와 process 관련 high-level로 만들어놓은 라이브러리를 concurrent.futures로 알고있습니다. 그 기반(low-level)은 threading과 multiprocessing으로 이해하고 있고요. 그런데 thread 강의에서는 대부분 concurrent.futures이용해서 multi-thread를 구현하셨는데, process 강의에서는 오히려 multiprocessing을 더 많이 쓰시는 것 같습니다. (concurrent.futures이용은 적어보임). 혹시 multi-processing은 concurrent.futures보다는 multiprocessing 라이브러리가 더 자주쓰이고 일반적인가요? 1. 숫자를 0부터1억까지 순서대로 더할때(0+1+2+...+1억), '1스레드/1프로세스'로 하는것과 '#스레드/#프로세스'로 하는것 중 어느것이 일반적으로 더 빠른가요? 잘은 모르지만... 숫자를 share하면서 가야하기때문에 (현재 어디까지 더한지를 알아야하니) '#스레드/#프로세스'는 굳이 switching(?)만 해야해서 더느릴것같은데... 이런생각이 맞나요? 더 나아가서 share하는 변수(상태를 연속적으로 알아야하는)가 있으면 하나의 스레드/프로세스에서 하는게 제일 빠르다고 생각해도 되나요? 2-1. parent thread/process에서 child thread/process를 만들고, 그 child가 할일을 다하면(더이상 실행할 코드가 없으면) 그것을 종료하는것이 자원관리에 효율적이라고 생각합니다. with문을 쓰면 자동으로 with문 내에서 정의된 child들이 다 끝나고 나서 with문을 나갈때 그 안에서 정의되었던 child들이 자원을 더이상 안쓴다고 생각하면 되나요? 그리고 역으로 with문은 with문 내에서 만들어진 child가 다 끝날때까지 with문 밖으로(들여쓰기 밖) 못나간다고 생각하는게 맞는 생각인가요? 2-2. 그러면 역으로 child는 무한으로 돌고, parent는 할일을 하고싶다면, with문내에서 그러한 child들을 정의하면 안될 것 같은데 (끝나지 않아 못나오니).... 이럴 경우에는 추후에 child가 끝나면, 제가 억지로 그 child의 자원사용을 막기위해 close(?)같은 걸 해야할 것 같은데... 어떻게하나요? 자동으로 파이썬이 작업을 안하는 therad/proecss는 자원을 안쓰도록 관리하나요? (ex. is_alive()나 .running()으로 찍었을때 False면 자원 안쓰도록) 3. (Thread부분이지만 Process에서도 동일할거라 생각) concurrent.futures.TheradPoolExecutor에서 submit을 통해 만들어지는 child thread가 daemon이 되도록 어떻게 설정하나요? threading.Thread로 만들때는 argument에 daemon=True을 하면, 만들어지는 child thread는 daemon이 였는데, 위 경우는 잘 모르겠네요... 4. concurrent.futures.as_completed(Future Object)는 그 Future Object가 그것의 thread/process를 끝내면 바로 어떤작업을 처리하도록 해놓는것이고, thread/process가 끝난 시점에서 return값으로 Future Object 가 있다! 라고 이해하면 되나요? 그리고 그 return값을 갖고 무엇인가를 할때는 parent의 thread/process에서 하는게 맞는것이죠? (그 Future Object가 갖고있던 child thread/process가 아니라) 5. (4번이어서) 그러면 4번의 경우는 child thread/process에서 어떤작업들을 다하고, 그것의 결과를 가지고, parent thread/process에서 추가적인 작업을 할때 사용을 하면 되나요? 6. multi-process를 할때, 그 process의 개수는 제한이 없나요? (제 컴퓨터가 4Cores, 8Logical processors라 하더라도 process는 8개가 최대고 이런것은 없는것이죠??? 마치 task manager의 performance를 보면 Processes가 엄청많이 돌고있는것처럼, 제가 multi-process를 한다는것은 Processes를 그만큼 늘린다는것이고, 그것들을 어떻게 잘 할지는 8개의 Logical processors를 갖고 운영체제가 알아서 할일이라고 이해하면 되겠죠?) ※ multiprocessing을 하실때, 여러 process들을 다 만들어 start를 시키시고, parent process에서 .join()을 하시던데... 관련 2가지 질문이 있습니다. (아래 7번/8번) 7. process A/B/C를 만들어 start를 시키면 parent/A/B/C가 parallel하게 실행이 될텐데, 결국에 (강의에서는 for문을 이용) 순차적으로 parent에서 A.join() > B.join() > C.join()이 되도록 하면 parallel이 더이상 유지되지 않는것 아닌가요? 즉... A.join()을 만나는순간 모든 process는 멈추고 A process만 진행되다가 그것이 끝나면 다시 parent/B/C가 parallel하게 진행되고, 곧 B.join()을 만나는순간 모든 process는 멈추고 B process만 진행되다가 그것이 끝나면 다시 parent/C가 parallel하게 진행되고, 곧 C.join()을 만나면 모든 process는 멈추고 C process만 진행되다가 그것이 끝나면 다시 parent가 진행되고... 이 순서가 아닌가요? 그러면 multi-process의 parallel이, join을 만나는순간 깨지는 개념이 아닌가요? 8. (만일5의 제 의견이 맞다면) multi process에서 main process가 끝나더라도, 다른 child process는 계속해서 진행을 할텐데 (daemon이 아니라면), 굳이 join()을 써서 parallelism을 깨는 이유가 있나요? thread에서는 잘 안쓰던 join인데, process에서는 join을 너무 당연하게 쓰셔서, 제가 놓치거나 모르는부분이 있나 싶어 여쭤봅니다. 9. multi-process의 변수 공유 관련하여 @ multiprocessing(4)-Sharing state 강의, 예시를 들어주신것이 parent process에서 share_value가 0이 나오고 '공유가 안되고있다' 라고 해주셨습니다. (강의 8분4초정도) 그리고 이어서 share_value를 다른 method에 (with 다른 process) 넘겼음에도 불구하고, share_value는 0이라고 해주셨습니다. 따라서 프로세스간 주소공간은 독립적이라고 해주셨는데... (프로세스간 object 공유가 안된다) 그런데 제 짧은 지식으로는, 이번경우는 mulit-process라서 공유가 안되었다기 보다는, 함수의 local변수와 그밖에서의 변수의 name space 때문이 아닌가요? 예를들면 아래코드 (single process) 에서도 share_value는 generate_update_number라는 함수를 다녀오더라도 0입니다. 그 이유는 share_value라는 object가 generate_update_number라는 함수안에서 한것은, return이 따로없다면, 그 밖에서는 영향이 없다! (제 짧은 지식으로는) 때문으로 이해가되는데... 혹시 아닐까요? (아래에 그대로 copy and paste 할 수 있도록 코드를 만들고, 실행결과도 붙였습니다.) ㅡㅡㅡㅡㅡㅡㅡ 코드 ㅡㅡㅡㅡㅡㅡㅡ def generate_update_number(v): print(f"[step2] v의 값 / id : {v} / {id(v)}") for _ in range(50): v +=1 print(f"[step3] v의 값 / id : {v} / {id(v)}") def main(): share_value = 0 print(f"[step1] share_value의 값 / id : {share_value} / {id(share_value)}") generate_update_number(share_value) print(f"[step4] share_value의 값 / id : {share_value} / {id(share_value)}") if __name__=='__main__': main() ㅡㅡㅡㅡㅡㅡㅡ 실행결과 ㅡㅡㅡㅡㅡ [step1] share_value의 값 / id : 0 / 140737278943616 [step2] v의 값 / id : 0 / 140737278943616 [step3] v의 값 / id : 50 / 140737278945216 [step4] share_value의 값 / id : 0 / 140737278943616
설계독학맛비's 실전 FPGA를 이용한 HW 가속기 설계 (LED 제어부터 Fully Connected Layer 가속기 설계까지)
안녕하세요 맛비님. 강의 매우 잘 보고 있습니다. 이번 강의 내용에서 lab10_main.c 코드를 분석해보다가 질문드릴께 있어 글을 작성하게 되었습니다. usleep 체크를 한 뒤 FSM을 돌리기 위해 i_run 신호를 발생시키기 전에 IDLE state를 체크하시는 부분을 확인해보고 있었는데요. do { read_data = Xil_In32 ((XPAR_LAB10_MATBI_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE)); } while ( (read_data & IDLE) != IDLE); 이 부분을 아래와 같이 수정해서 어떤 값을 읽고 있는지 확인해보았습니다. do { read_data = Xil_In32 ((XPAR_LAB10_MATBI_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE)); printf ( "current state is %d \n " ,read_data); } while ( (read_data & IDLE) != IDLE); 출력되는 값이 5였습니다. 이 말은 IDLE과 DONE이 모두 active high라는 상태 같아서 제가 제대로 이해한게 맞는지 궁금합니다. 연계해서 한가지 더 궁금한점은 do while문이 iteration 하는 횟수가 PL에서 동작하는 클럭과는 무관하게 돌아가는거 같은데요. 이 부분은 DONE 신호를 기다리는 파트에서 마찬가지로 printf 넣어서 갯수를 한번 세어봤거든요. data로 1M을 입력 했으면 do while문도 1M 번 반복할 줄 알았는데 훨씬 많은 횟수의 iteration을 도는 것으로 보이는데요. 이 부분은 PS와 관련이 있는 걸까요? 너무 기초적인걸 질문드리는건 아닌지 조심스럽지만... 용기내어 질문드려봅니다. 감사합니다.
안녕하세요 윤상석 강사님. TypeORM의 트랜잭션 관련으로 질문이 있습니다. TypeORM에서 트랜잭션을 다루는 방법은 이전 질문글 에 답변해주셨듯이 크게 3가지인 것으로 알고 있습니다. 1. QueryRunner 2. getConnection, getManager 3. @Transactional 개인적으로는 @Transactional() 데코레이터를 사용하는것이 편리하여 사용하고 있었는데요. NestJS 공식문서 에서 데코레이터를 이용하는 것을 권장하지 않고 있고, 구글링을 해보아도 유닛 테스트에 어려움이 있어 권장하지 않는 분들이 많은 것을 알게되었습니다. 여기서 첫 번째 질문이 있습니다. Q1. "유닛 테스트에 어려움이 있다"는 이야기가 구체적으로 무슨 의미인지 궁금합니다. 모킹이 어렵다. 내 마음대로 제어가 불가능하다 등의 이야기가 이해는 가는데 와닿지는 않아서 질문드립니다. ---- QueryRunner 방식을 이용하게 되면 try-catch-finally 코드가 강제가 되는 것 같아보입니다. 여기서 두 번째 질문이 있습니다. Q2. 모든 에러를 감지하는 Filter를 적용해두었다면 QueryRunner를 사용하는 try-catch-finally 구문에서 에러 처리를 해버려 필터가 작동하지 않을 것 같은데 맞을까요? 맞다면, 만약 Filter에서 요청이 실패하였을 때의 로깅기능이 있다고 가정한다면 로깅기능이 작동하지 않을 것 같습니다. 그렇다면 catch 문에서 따로 Filter에서 구현한 로깅을 다시 구현해주어야 할까요? ---- 트랜잭션 처리를 도와주는 typeorm-transactional-cls-hooked 패키지를 발견하였습니다. 여기서 마지막 세 번째 질문이 있습니다. Q3. 해당 패키지는 유닛 테스를 할 때 트랜잭션 기능이 작동하지 않도록 모킹기능도 제공해주는 것 같습니다. QuerryRunner 보다 안 좋은점이 있다면 어떤 점이 있을까요? ---- 질문이 너무 많은 것 같아 죄송합니다. 좋은 강의와 답변해주셔서 항상 감사합니다.
minikube start --driver=hyperv 명령 어를 입력하면 이런 장애가 나는데 어떻게 해야하나요? hyperV 를 비활성화하고 virtual box로 하면 This computer doesn't have VT-X/AMD-v ena bled. Enabling it in the BIOS is mandatory 이런 에러가 나면서 시작실패를하는데 어떻게 해야할까요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 네 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 모르겠어요 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 네 [질문 내용] 4:37분쯤에 나오는 Assertions.assertThat 메소드는 지원하지 않는것으로 나오는데요 ㅠㅠ(빨간색) Asseertions의 다른 메소드들(assertionAll 등...)은 자동완성이 되는데 저 메소드를 쓰려면 따로 import 해야하는 설정이 있을까요?
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요. 저는 토목전공 대학원생입니다. 선생님 강의를 통해서 머신러닝에 대해서 공부를 하고 있습니다. 먼저 비전공이기 때문에 컴퓨터 언어와 머신러닝 기법에 능숙하지 않은 점은 미리 양해를 구합니다. 현재 저는 가지고 있는 실험 데이터를 머신러닝에 접목시키는 시도를 하고 있습니다. 제가 가지고 있는 데이터는 회귀분석이 적합한 것 같아서 기초 개념부분이랑 회귀분석 파트를 주로 집중해서 공부를 했는데요, 엑셀 데이터 파일을 파이썬으로 가져와서 회귀분석하고 RMSE 값을 평가하는 것 까지는 그럭저럭 잘 따라온 것 같았습니다. 데이터의 내용을 간략하게 말씀드리면 흙의 일축압축강도를 UCS라고 하는데 UCS를 결정짓는 여러 파라미터를 가지고 UCS 값을 예측하고자 하였습니다. 그래서 UCS가 Output 이고 input 값들로는 폴리머의농도(1.0, 1.5, 2.0, ...), 초기함수비(20, 30, 60, ...) 테스트함수비(0.32, 2.33, 60.23, ...), 건조 단위중량(1,23, 1,35, ...), 흙의 종류(CL, SP, SP-SM), 실험조건(건조, 침수, 초기상태) 등 이 있습니다. 데이터 프레임을 보여드리면 아래와 같습니다. 아무튼 이렇게 해서 강의 내용을 따라 회귀 분석은 마쳤는데요 제가 궁금한건 이 분석 후에 새로운 데이터가 있을 때 그 데이터의 UCS 값을 어떻게 얻을 수 있는지, 입니다. 혹은 회귀식이나, 함수를 얻을 수 있는지, 입니다. 그리고 이 데이터가 회귀 분석을 하는 것이 적절한 걸까요..? 제가 이 분야에 지식이 많이 부족해서 계속 공부하고 검색해서 찾아보곤 있는데 혼자서 공부하는 거라 궁금한 점이 속시원히 해결이 잘 안됩니다ㅠㅠ 막무가내의 질문일 수도 있을 것 같은데,, 도움을 청할 곳이 선생님 밖에 없는 것 같습니다ㅠㅠ 어떤 챕터의 강의를 더 자세히 들어보라거나, 어떤 자료를 참고해라 정도의 답변도 좋습니다! 답변 기다리겠습니다. 감사합니다.
배운 내용대로라면 소멸자는 동적할당 해제 즉 delete 가 실행되어야 소멸자가 호출이 된다라고 배웠는데 그렇다면 소멸자로 delete 를 호출할수 없는거 아닌가요. 제가 무언가 잘못 이해한거일수도 있겠네요 이거 질문하신분 있을거 같은데 명확하지가 않은거 같아 다시 이렇게 질문드립니다
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 선생님, 항상 좋은 강의 해주셔서 감사합니다. 다름이아니라, 분류모델링 중 불균형이 심한 데이터 (0이 95% 이상, 1이 5% 남짓)를 처리하는 모델링을 현업에서 진행중인데, 컬럼의 수도 매우 많은 편이라 feature engineering 중 어려움을 겪고 있습니다. 재현율이 핵심인 모델인데, feature가 재현율에 미치는 영향을 알려주는 지표나 guideline같은 것이 있을까요? 없다면 재현율의 저하를 야기하는 feature의 특징을 알 수 있을까요?? 항상 감사합니다!
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 교수님! 인터넷 강의 신청해서 듣고 있는 학생입니다. 혹시 수업 내용에 쓰이는 PPT자료를 따로 공유 해주실 수 있으신가요? 인터넷 강의를 들을 때 더 편하게 들을 수 있을 것 같습니다. 감사합니다!
유니티의 모든 기능은 코드화가 가능하다라는 전제를 염두에 두고 공부하고 있습니다. 1.애니메이터 컨트롤러는 어떻게 이해해야 될까요? 게임오브젝트와 같은 클래스인가요, 콤퍼넌스일까요? 2. 여러 STATE를 PLAYERCONTROLLER에 넣는 것을 보았는데 이것들은 각각 CLASS일까요?
강의 내용에 있어서 변수를 초기화하는 방법이 2가지 즉 매개변수에 직접 값을 대입하는 방법이랑 생성자를 이용해서 값을 초기화 하는 방법 이 2가지가 있다라고 배웠는데요 강의 내용에서처럼 두가지 모두 초기화되어있을때, 생성자에서 초기화된 내용을 우선시한다 라고 했는데 그렇다면, 순서가 매개변수에 있는 내용의 초기화 부분은 아얘 건너뛰고 생성자 부분의 초기화만 실행하는 것으로 이해하였는데 제가 이해한것이 맞는지 궁금합니다. 즉, 초기화를 2번할수는 없으니까 말이에요 또한가지 질문이 있는데요 이강의에서 나온 생성자 멤버 초기화 목록으로는 다른 클래스 뿐만 아니라 배열도 초기화가 가능한데, 전에 배운 고전적인 생성자 방식으로는 위의 두가지 즉 클래스와 배열을 초기화 할 수가 없더라고요. 혹시 방법이 있는건지 아니면 아얘 불가능한건지 알고싶습니다. 답변해주셔서 정말 감사합니다. 혹시몰라 예제코드도 첨부합니다. using namespace std; class Test { int num; public: //Test(const int& num) //{ // this->num = num; //} Test(const int& num = 0) :num(num) { } }; class Date { int m_year; int m_month; int m_date; int m_arr[5]{11,22,33,44,55}; Test num{1}; public: Date(const int& m_year = 1900, const int& m_month = 1, const int& m_date = 1) { this->m_year = m_year; this->m_month = m_month; this->m_date = m_date; } //Date(const int& year = 0, const int& num = 0) : // m_year(year), // m_month(11), // m_date(24), // num{num}, // m_arr{ 1,2,3,4,5 } //{ // m_year = 4535; //} void setDate(const int& m_year, const int& m_month, const int& m_date) { this->m_year = m_year; this->m_month = m_month; this->m_date = m_date; } void setYear(const int& m_year) { this->m_year = m_year; } int getYear() { return this->m_year; } int getMonth() { return this->m_month; } int getDate() { return this->m_date; } void copyThis(const Date& original) { this->m_year = original.m_year; this->m_month = original.m_month; this->m_date = original.m_date; } void printArr() { for (auto n : m_arr) { cout << n << " "; } cout << endl; } }; int main(int argc, char* argv[]) { //Date date = (2021, 11, 24 , 555); Date date(2021,555); cout << date.getYear() << " " << date.getMonth() << " " << date.getDate() << endl; date.printArr(); }
Vagrant up 수행 시 하기와 같이 에러가 뜹니다.. 테스트 OS는 Mac이고, Virtual Box 버전은 6.1.28 r147628입니다. ======================================= VWS_vagrant_script % vagrant up Bringing machine 'cent1' up with 'virtualbox' provider... Bringing machine 'cent2' up with 'virtualbox' provider... Bringing machine 'cent3' up with 'virtualbox' provider... ==> cent1: Checking if box 'centos/8' version '2011.0' is up to date... ==> cent1: Clearing any previously set network interfaces... The IP address configured for the host-only network is not within the allowed ranges. Please update the address used to be within the allowed ranges and run the command again. Address: 172.18.1.91 Ranges: 192.168.56.0/21 Valid ranges can be modified in the /etc/vbox/networks.conf file. For more information including valid format see: https://www.virtualbox.org/manual/ch06.html#network_hostonly