왜 파이프 1프로세스 멀티쓰레드 상황이나
1쓰레드 안에서 자기 자신한테 비동기로 보내는 상황이나 이런거 안하는거야?
가 요지고
복붙 하나만 할게
파이프 이론상 자기 자신과 연결될수도 있는거 아니야?
그거 그리고 여럿이서 공유도 가능한거같던데
그냥 파일디스크립터 두개 나오는거
아무렇게나 나눠가져서
읽기쪽에서 읽을사람 쓰고
쓰기쪽에서 쓸 사람 쓰면 되잖아
자기 자신한테도 쓰고, 멀티쓰레드에서도 쓸 수 있는거잖아
보니까 이 용도로 쓰라고 메세지 큐가 있는거 같던데
파이프는 왜 이 용도로 쓰면 안됨?
내가 메세지큐 잘 모르긴 함
그리고 이 문제의 핵심 착안은 뭐였냐면
어떤 한 함수에서 이벤트를 발생시키고
다른 한 스레드(혹은 비동기함수)에서 이벤트를 기다리다가 실행하면 되겠다
그 자바스크립트 promise.resolve 라던가 Event dispatch인가 그거를 간편하게 자바에서 구현해보고 싶다는 생각이 들어서(어디까지나 그냥 개발공상이지 실제 개발용도로 생각하는건 아님)
그러면서 또 남들한테 이벤트 발생시키는건 소켓에 read/write 걸면 되니까 쉬운데
자기 자신한테 이벤트 거는건 어떻게 가능할까?
뭐 이런 생각에서 출발했음.
그래서 지금 내가 그냥 아무렇게나 내 아는지식으로 휘갈기면
그냥 파이프 하나 파고
멀티쓰레드일경우엔 한쓰레드 파서 파이프 하나에 반복문으로 read 걸면 될거고
비동기 1쓰레드일 경우, 즉 아예 자기 자신 쓰레드에다가 이벤트 발생시키는 경우에는 이거는 시그널 가야하는거같고, (인터럽트를 발생시킬순 없을테니)
이제 자바스크립트처럼 1쓰레드이지만 이벤트루프라는 개념이 존재하는 경우에는 (그 이벤트 루프가 인터럽트 기반의 1쓰레드이건 멀티쓰레드이건)
이벤트루프가 epoll로 깨어나면 되겠군
이라고 결론지었어
내 공상 좀 발전시켜주라.
(1) 너희라면 자바 혹은 C로 자바스크립트의 이벤트 발생 혹은 promise.resolve로 원샷 만드는거 어떻게 할래?
(2) 혹시 이런거 전문으로 하는게 메세지 큐니? 나 메세지큐 전혀 몰라. 카프카 뭔지도 모름
난 이런 공상이 재밌더라고. 내가 아는것들이 게슈탈트붕괴되면서.. 잠깐... 왜 이런게 당연한거지? 싶고, 이거 뭐 자바쓰다가도 자바스크립트에서 쓰던 버릇 쓰고싶으면 써도 되잖아?(실무에서 쓰겠단건 아니지만) 뭐 이런게 좋음 그래서 내가 주언어로 가져가는 클로저도 언어의 패턴이나 효율성?이 정형화된 언어보다 그 형태가 유연해서 내가 아는것을 이것저것 활용할수록 재미난 언어로 골랐고
메세지큐를 모르는 지금 현 상태에서는, 약간 스프링 쓰면서 REST API 는 @RequestMapping RestController로 처리하고 또 나만의 파이프? 이벤트핸들러? 같은거 만들어서 @MyEventMapping("sampleEvent") 같은 컨트롤러 자작해서 만들어서 쓰면 재밌겠다 싶었음. 아마 이런거 필요할때 카프카 쓰는거겠지?
그래서 @MyEventMapping("sampleEvent") 와 EventEmitter.emmit("sampleEvent") 는 어떻게 구현할래? 라고 했을때 나는 일단 파이프가 떠오르더라. 자바같은경우는 멀티쓰레드로 쓰겠지만. epoll 로 비동기로 만드는건? 아예 완전한 1쓰레드로 하려면 시그널 써야하나? 지금 여기까지 생각이 왔음
방법은 여러가지 있는데 좀더 재밋게 하려면 캐릭터 디바이스하나 만들어서 쓰면 됨. 너가 말한대로 각각의 스레드에서 파일디스크럽터로 해당 캐릭터 디바이스 오픈하고 read/wirte만하면 데이터 주고 받을 수 있도록 하는거지. 캐릭터 디바이스 안에 chardev operation 정의하는 부분이 있는데 여기 안에서 각 디스크립터 별로 이벤트를
보내고 받게끔 할 수있음. 이거 하나를 잘 만들어두면 기존 파이프에서 부족한 부분을 너 맘대로 입맛에 맞게 만들 수 있는거임. 그리고 만드는 방법과 구현방법은 자기 입맛대로 하면됨. localhost로 소켓 뚫고 send,recv로 로컬 스레드에서 주고 받으면 그걸로도 충분히 구현 가능한거임.
논블록킹으로 하고 싶으면 select나 poll, epoll 쓰면 되는거고
맞아 맞아 근데 파이프도 가능할거같고. 이폴이든 시그널이든 연결해서 더 재밌게 쓸수있고 캐릭터디바이스로 최적화하고 데헷 그럼 나 이거 하나만 답변해줘 이런 기능이 근데 생각해보면 꽤나 유용하고 필요한 기능이잖아? 실무에서 분명 쓰고있을거라고. 근데 그사람들이 파이프쓰고있진 않잖아 이 역할이 메세지큐 맞아? 카프카
이거 실무에서 무조건 쓰고있을텐데. 글고 이미 그 예시가 자바스크립트의 프로미스 아녀?
자바에는 프로미스가 없는데 그러면 라이브러리로 프로미스같은걸 쓰겠지. 그게 카프카임?
내 경험상 메시지큐는 잘 안쓰고 속도 땜시 디바이스 드라이버에서 제어 했던거 같음 read write도 안쓰고 ioctl로 다 구현하는 방식으로. 일반적인 유저영역의 세마포어 뮤텍스보다 tick 올려서 커널에서 쓰는 시그널 세마포어가 더 빠르기 땜시.
내가 자바는 안해봐서 모르겠는데 자바도 캐릭터 디바이스 오픈해서 ioctl 은 호출될꺼잖아? 디바이스 드라이버로 만드는게 젤 깔끔해보인다. 어느 언에에서든 사용 할 수 있고.
아 세마포어로 블록시켜놓는다? 세마포어로 블록시키고 셈포안에 메세지담고 세마포어 해제시켜서 들어오게 하고? 세마포어를 컨슈머 프로듀서 구조로 만드는거 고민해본적이 별로 없었네
약간 일부러 락을 잡아두고 안푸는건데 뮤텍스는 이렇게 쓰지 말라는거같고 세마포어는 이런 용도로도 설계된것같군
근데 락 걸린거 해제되는것도 epoll이 가능함?
정말로 성능이 중요하면 커널 단에서의 비지웨잇을 고려해봐도 좋음.
여기서 구분 잘해야하는게 epoll은 chardevice의 fd set 이벤트에 의해서 사용되는 "유저영역"인거고 내가 말한 시그널 세마포어나 비지웨잇은 "커널영역"임
epoll에서 timeout 전에 락푸는건 fd set에서 이벤트 플래그 켜주면 풀리는거징
좀더 공부하고올게 ㅠㅠ 실무경험이 없고 나 epoll을 솔직히 써본적이 없음 ㅠㅠ
epoll은 윈도우의 iocp를 흉내내기 위에서 나온거라고 생각하면 좀더 편함. 좀더 쉽게는 select 보다 우아하게 쓰기 위해서 poll 나왔고 좀더 대규모로 처리를 위해서 epoll 나온거
아 시발 세마포어 이거는 카운트가 자원수(메세지큐)고 자원이 있으면 들어와라니까 이거 프로듀서 컨슈머 구조구나 나 바보네 ㅠㅠ 좀 더 공부할겟 ㅠㅠ 많이많이 고마워
ㅎㅎ ipc에서 자주 등장하는 shm 도 같이 공부해두면 좋음 화이팅 수고링
공유메모리고마왕
다 이해했다.근데 비지웨이트만 이해 못함.좀만 설명해줘일단 커널스레드가 비지웨이팅하고커널 공유변수를 안전하게 계속 체크하는 상황?그러면 유저프로세스에서는 걜 이용하려면 시스템콜로 커널스레드발생?이순간 커널스레드랑 유저프로세스통신은 또 ipc쓰고?
사실 별거 없어 시나리오로 설명해주자면 A가 데이터를 받기 위해서 Recv 동작을 취하면 데이터가 들어오기전까지 시그널 웨잇 또는 비지 웨잇을 하는거임 B가 데이터를 보내기 위해 Send 동작을 하면 공유 메모리에 데이터 쓰고 A에게 시그널을 보내거나 비지 웨잇을 풀어주는거임 그럼 A는 시그널을 받거나 비지웨잇이 풀리면 그제서야 데이터를 읽어가는거고
이걸 FDSET을 이용하면 select나 epoll이 들어가는거고 디바이스 드라이버에서 직접 구현하면 아까 말한 세마포어니 비지웨잇이니 이런게 필요한거고 내 경험상 커널에서 직접 핸들링하는게 더 빨랐음
내가 이렇게 까지 했던게 40Gbps 통신 모듈 드라이버 구현 할 때 였거덩 그래서 레이턴시를 최대한 줄여야했어
아 공유메모리써서 비지웨이팅이구나 근데 난 그거 싫어서 파이프쓰는거긴 해
챗지피티피셜 1프로세스 멀티쓰레드는 힙을 공유하니까 파이프 안쓴다더라 난 그게 좀 이해가안갔었음
상황봐가면서 개인 취향대로 만들면 돼 ㅎㅎ
결국 시그널이나 비지웨이팅 쓰란거잖아
시그널대신 파이프쓰고싶은데 챗지피티가 자꾸 1프로세스 멀티쓰레드라던지 1쓰레드에서는 파이프 절대안쓴대
내가 보니 세마포어가 제일 깔끔하다
파이프는 1스레드에서 안쓰는게 보내는놈과 받는놈이 분리되어야해서... 근데 동일 스레드 내에서 주고 받을꺼면 메모리 할당 하나 해놓고 뮤텍스 걸어가면서 플래그보고 주고 받고 하면 되는거 아니야?
아니지 동일 스레드면 뮤텍스조차 필요 없는디 순차니께..
1프로세스 멀티쓰레드는? 글구 1쓰레드같은 경우도 한쪽끝에 write하고 비동기로 컨텍스트스위칭해대면서 try_read 하면 되는거 아냐?
난 자바스크립트같은거 생각하는거
자바스크립트는 사실 이벤트루프라는 쓰레드 만들긴 하니까 그냥 멀티쓰레드상황얘기긴 함
아 잠깐 ㅇㅈ 1쓰레드의 경우는 그냥 내부 변수 자기가 체크하면 된다 ㅇㅇㅇ 굳이 try read 할 필요가없네
흐음.... 이게 결국은 시그널밖에 없네 무한폴링 안하려면
아니면 쓰레드하나를 엄청 무겁게 운영체제처럼 만들던가
(계속 시분할들어가게)
흠.. 적당히 쪼개쓰는 것도 방법임 ㅎㅎ