월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 선생님 질문이있습니다.
1번 : depth라는 것이 정확히 무엇인가요? 인자로 들어온 xml을 파싱을 할 때 int depth = r.Depth + 1; 로 갱신을 해주고 while(r.Read()) { if (r.Depth != depth) break; .... 이부분이 이해가 안가고 2번쨰 : PacketFormat 하는 부분에서 {0}, {1} {2} 이런식으로 대체를(?) 한다 라고 설명하셨는데 정확히 어떤 의미 인지 모르겠습니다. switch (memberType) // *** 패킷 타입 케이스별로 패킷 "자동화 부분"을 넣어줌 { case "byte": case "sbyte": memberCode += string.Format(PacketFormat.memberFormat, memberType, memberName); readCode += string.Format(PacketFormat.readByteFormat, memberName, memberType); writeCode += string.Format(PacketFormat.writeByteFormat, memberName, memberType); break; case "bool": case "short": case "ushort": case "int": case "long": case "float": case "double": memberCode += string.Format(PacketFormat.memberFormat, memberType, memberName); readCode += string.Format(PacketFormat.readFormat, memberName, ToMemberType(memberType), memberType); writeCode += string.Format(PacketFormat.writeFormat, memberName, memberType); 멤버 타입 별로 파싱을 해서 memberCode 부분과 readCode, writeCode 부분이 각각 {0}{1}{2} 인가요? 이해가 ㅠ.ㅠ
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
실행시 자동으로 실행된다고 하셨는데
해당 방법은 디버그시 알아서 배치 파일을 열어준다는 의미인가요? 그렇다면 어떻게 할 수 있을까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 메모리 배리어 강의 부분 관련해서 질문드립니다.
using System; using System.Threading; using System.Threading.Tasks; namespace ServerCore { class Program { static volatile int x = 0; static volatile int y = 0; static volatile int r1 = 0; static volatile int r2 = 0; static void Thread_1() { y = 1; //store y r1 = x; //load x } static void Thread_2() { x = 1; // store x r2 = y; //load y } static void Main(string[] args) { int count = 0; while(true) { count++; x = y = r1 = r2 = 0; Task t1 = new Task(Thread_1); Task t2 = new Task(Thread_2); t1.Start(); t2.Start(); Task.WaitAll(t1, t2); if (r1 == 0 && r2 == 0) break; } Console.WriteLine($"{count}번 만에 빠져나옴"); } } } 메모리 배리어 강의에서는 위 코드의 루프를 거의 100번 이하로 빠져나오는데 제가 했을때는 적으면 8000번 많으면 10만까지 루프를 돌더라구요. 어떤 차이점 때문에 이렇게 루프 반복 횟수가 차이나는 걸까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 선생님 코드 몇줄에 대해서 질문드립니다.
질문 SocketAsyncEventArgs _sendArgs = new SocketAsyncEventArgs(); SocketAsyncEventArgs _recvArgs = new SocketAsyncEventArgs(); 의 정확한 개념에 대해서 질문합니다. 세션 클래스 내부에서 SocketAsyncEventArgs _sendArgs = new SocketAsyncEventArgs(); SocketAsyncEventArgs _recvArgs = new SocketAsyncEventArgs(); public void Start(Socket socket) { _socket = socket; _recvArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnRecvCompleted); _sendArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnSendCompleted); RegisterRecv(); } void RegisterRecv() { _recvBuffer.Clean(); ArraySegment<byte> segment = _recvBuffer.WriteSegment; _recvArgs.SetBuffer(segment.Array, segment.Offset, segment.Count); bool pending = _socket.ReceiveAsync(_recvArgs); if (pending == false) OnRecvCompleted(null, _recvArgs); } 비동기의 개념을 가지고 해석을 해봤는데, 서버 의 메인 함수 쓰레드가 메인 함수를 실행을 하면서 리슨을 던져놓고 클라이언트의 커낵트 신호가 올때 쓰레드 풀에서 대기하고 있던 A쓰레드가 투입이됩니다. 이때 메인 쓰레드는 while()문을 계속해서 타고 있기에 프로그램이 종료가 되지 않고 있는 상황. A 쓰레드가 클라이언트를 Accept를 등록해주고 Accept를 완료 시킴으로써 클라와 서버 내부의 클라세션의 연결이 완료가 되고 SEND와 RECEIVE를 하면서 서로 통신을 하게 되는데 세션 클래스 내부에서 SocketAsyncEventArgs _sendArgs = new SocketAsyncEventArgs(); SocketAsyncEventArgs _recvArgs = new SocketAsyncEventArgs(); --> 이것이 클라이언트 세션 내부에서 SEND를 전담하는 쓰레드 A와 RECEIVE를 전담하는 쓰레드 B를 쓰레드 풀에서 가져와서 서버 클라이언트 세션에는 쓰레드 2개가 활동을 하는것이고 이 쓰레드는 비동기로 활동을 하는 건지 아니면 쓰레드 하나가 A라는 클라이언트를 전담하는 서버 컴퓨터의 A라는 클라이언트 세션에는 하나의 쓰레드가 있고 이 쓰레드를 비동기로 만들어주어 Receive와 send 신호오면 투입할 수 있게 콜백 걸어놓고 receive 신호 오면 receive 처리 처리중에 send 신호오면 기억해 두었다가 send 처리 이런식인가요 그리고 쓰레드는 만약 c++ 이라면 해당 cpp 파일 당 쓰레드를 하나씩 분배를 하나요? 함수 단위로 쓰레드를 분배를 하고 쓰레드 풀로 수거가 되나요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Session #2 강의 _pending 변수 질문입니다.
안녕하세요! 정말 이만한 게임서버에 관한 강의가 없는데 감사히 수강하고있습니다! Session #2 강의 보다가 질문을 올립니다. 아직 Session #2까지밖에 안봐서 인지는 모르지만 _pending으로 분기처리를 하는 부분이 왜 필요한지 모르겠습니다. 이미 _lock으로 들어왔으면 다른스레드는 못들어올 텐데 _pending으로 한번 더 분기해서 큐에만 넣고 빠져나올지 아니면 `RegisterSend`까지 해줄지를 결정하는 부분입니다. _lock에 들어오고 다른 쓰레드가 _pending으로 분기할 경우가 있을지 제 눈에는 도저히 판별하기가 힘드네요 ㅠㅠ 그런 경우가 생기나요?? 우선 _pending의 추가적인 분기없이 실행해도 정상작동합니다! 감사합니다!
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
패킷 사이즈 질문..
안녕하세요..? 예전에 수강했던 학생인데 다시 돌려보고 있는 중입니다 ㅎㅎ.. 바로 질문 들어가겠습니다. 패킷을 작성할 때 패킷 헤더라는 것에 공통적으로 패킷 id와 패킷 size를 넣는데, 패킷 id의 존재이유는 확실하게 알겠습니다. 그런데 패킷 size는 왜 필요한지 잘 모르겠습니다. 패킷 size라는 것이 네트워크상 데이터를 전송하기위해 필요한 파라미터라기 보다는 어느 정도의 데이터가 주고 받아졌다를 확인하는 용인지.. 아니면 보안상의 어떤 문제를 해결하기 위해 집어넣는 것인지 모르겠어요 ㅠ 리스트 같은 경우에는 개수 같은게 중요하니 데이터를 입력하기 전에 미리 데이터 사이즈를 집어넣는 것은 이해가 가지만.. 패킷 전체의 사이즈를 미리 알아야 하는 이유가 있나요..?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 선생님 전체적인 구조에 대해서 질문 드립니다.
질문 1 : 클라이언트 세션에 대해서 수업 하신 내용이 클라이언트 1명이라고 가정 하셨을 때 내용인데 , 리스너에서 클라이언트 연결 신호가 오면 Accept를 해서 A라는 클라이언트에게 A 클라이언트 세션을 하나 주어서 , A 클라이언트는 A 세션을 통해서 서버와 패킷을 주고 받고 통신을 한다 만약 클라이언트가 1000명이라고 접속 했다고 했을 때 클라이언트 세션은 1000개가 만들어 지나요??? 질문 2 : 클라이언트 세션이 정확히 하는 일이 무엇인가요? 이해가 잘안되서 제가 비유를 만들어서가 예를 들어 보겠습니다. 제가 게임에 접속해 채팅 패킷을 보냅니다. 이 패킷에는 뭐 채팅 타입 (전체냐, 일반이냐, 귓말이냐)랑 채팅 내용을 캡슐화를 시켜서 서버에게 보내고, 서버가 이 패킷을 파싱해서 일반이냐 전체냐 귓말이냐를 판단을 해서 패킷 처리 를 하고 채팅 타입에 맞는 채팅 범위에 있는 클라이언트에게 뿌 려주는 구조. 이때 클라 1000명이 게임에 입장을 하면 일단 해당 000 게임 서버 컴퓨터에 연결이 되어 있다는 소리이 고, 서버 컴퓨터 내부에는 "각각" 클라 1000명에 대한 세션이 마련되어 있고, 클라가 1000명이 채팅을 패킷을 쏘면 서버 컴퓨터 내부의 "각각의" 클라 세션에 패킷이 전달이되고 TCP 구조니까 순서보장 즉, 먼저 온 패킷부터 서버 컴퓨터가 1000개의 클라 세션에서 받아서 패킷 처리를 한다. --> 제가 이해한 부분이 맞습니까 선생님? 너무 헷갈립니다. 처음에 다 그런거 겠죠?? ㅠ.ㅠ 추가적인 질문 선생님 따로 이메일 이나 그런게 없어서 여기다 질문 드립니다. 선생님꼐서 현업 개발자 이면서 가르치시는 선생님으로 알고 있는데요 저번에 질문 주실때 코딩테스트 난이도는 삼성이나 카카오 정도로 어렵지 않다라고 하셨는데 제가 넥X, 을 목표로 준비를 하고 있습니다. 영어 지문이라고 하는데, 프로그래머스 LV2,LV3 정도 문제 풀이를 하나하나 하고있는데, 이럴거면 해커랭크를 가지고 이용해야하는지 그리고 어떤 분은 온라인 코딩테스트가 어렵다고 하고 어떤 분은 쉽다고 그러고, 선생님께서 저번에 말씀해주신 왠만한 학교에서 배우는 자료구조 손코딩 이며, 설명 가능하 고 문자열 뒤집기등 문자열과 관련된 함수 같은거 10개정도 회문, 뭐 기타 구글에서 검색해서 나올수 있는 손코딩은 전부다 모아서 외우고 설명 준비를 했는데 수업시간에 선생님께서 넥X ,엔X 면접도 보셨다고 하셨는데 그때 당시 온라인 코테 난이도가 어느정도였으며 그떄 당시 선생님꼐서는 코테 어떻게 준비 하셨나요? 뭐 알고리즘 책 저번에 추천해주신거 그때 당시 선생님꼐서 는 깊게 공부하시지 않으셨던것 같은데 질문이 길어져서 죄송합니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 궁금한게 있어서 질문 드려봅니다
다름이 아니라영상의 27분 50초 쯤 SendBuffer에 대해서C++일경우에 레퍼런스 카운트를 이용해서 0이라면 풀에 반환한다고 말씀하셨는데요.C#에서도 아래처럼 1) 가능한 부분이 아닌가 싶어서 궁금해서 질문드려봅니다TLS 환경에 일정량의 SendBuffer Pool을 만들어 놓고 TLS환경에는 싱글스레드 처럼 하나의 스레드만 접근이 가능하므로 SendBuffer.Open시에 SendBuffer에 FreeSize가 reserveSize보다 크면 Pool에 반납을 하고 새롭게 미리 할당된 메모리를 가져오고 기존 메모리를 초기화해서 다시 풀에 넣는방식이라면 가능하지 않을까 싶은데 어떻게 생각하시는지 궁금합니다 추가질문 입니다. 2) 아래와 같은 이유로 SendBuffer를 새로 할당한 것인가요?C++의 레퍼런스 카운트를 이야기한 부분이 혹시Send시에 SocketAsyncEventArgs의 BuffList에 ArraySegment값들이 들어가고(원본의 참조형태로 들고 있기 떄문에) 그걸 Socket.SendAsync에서 호출하게 되는데 커널단에서 실제 Send 처리 이후의 메모리의 레퍼런스 카운트 시점을 알아야 정확히 풀로 반환할 수 있기 때문인건가요? 위와 같은 문제라서SendBuffer는 새로 할당하는 방법을 선택하신건지도 궁금합니다 3) C#에선 풀은 세션 별로 버퍼 풀방법 뿐인건가요?결국 레퍼런스 카운트 때문이라도C#에선Pool을 활용하려면 결국 세션 단위로 버퍼풀을 만들어서 사용하는 방법뿐일까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 선생님 backlog : 최대 대기수 에 대해서 질문 드립니다.
class Listener { Socket _listenSocket; Action<Socket> _onAcceptHandler; public void Init(IPEndPoint endPoint, Action<Socket> onAcceptHandler) { // 문지기 생성 : 첫번째 인자에 네트워크 주소를 넣어줌 _listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); _onAcceptHandler += onAcceptHandler; // 연결 // 문지기 교육을 시킴 : 식당 주소와 포트번호를 기입 _listenSocket.Bind(endPoint); // 영업 시작 : 리슨 소켓을 리슨 상태로 둔다. // backlog : 최대 대기수 _listenSocket.Listen(10); // *** 초기화를 하는 시점에 등록을 해줄 것 // 이 상태에서 클라가 connect 요청이 왔다고 한다면 // 콜백 방식으로 OnAcceptCompletd 함수 호출 된다. // 비동기 방식으로 예약만 하는 것 // 낚시대를 10개를 꼽아 놓는다. 물고기가 많으면 ... // 문지기 10개 버젼 for(int i = 0; i<10; i++) { // 문지기 1 버젼 SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.Completed += new EventHandler<SocketAsyncEventArgs>(OnAcceptCompleted); RegisterAccept(args); } } 수업 예제 코드 중에 Listen 클래스 를 작성하실 때 리슨 소켓 하나 만들어주고 그놈을 서버 컴퓨터에 바인딩을 시켜준다음 리슨 함수를 호출해 주고, 이상태에서 클라쪽에서 신호가 오면 그 다음 처리를 해주는 코드 설명이셨는데 여기서 리슨 함수 인자를 10으로 놓고 for문을 10번 반복 하셔서 문지기를 10개를 생성하셨습니다. 질문 : 최대대기수가 10이라는 얘기는 클라이언트가 10명이 접속 한다는 얘기 인가요? 그래서 문지기를 10개를 생성 해주셨는지 이게 맞다면 클라이언트 접속이 대략 1000명을 예상한다면 리슨 함수 인자로 1000을 넣어줘야 하나요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 선생님 동기식 비동기식 에 대해서 질문드리고, 서버 코드 공부 방법에 대해서도 질문 드립니다.
수업에서 궁금한 점이 2가지 정도 있어서 질문드립니다. Q1 ) 제가 동기식 VS 비동기식 제대로 이해하고 있는지 질문드립니다. 게임에서는 무조건 비동기식으로 사용해야 한다. 왜냐하면 언제 클라이언트가 CONNECT 요청 들어 올지 모르는데 Accept 걸어놓고 계속해서 메인 쓰레드는 다른 일을 하지못하고 connect 신호 올때 까지 기다리고 있기 때문에 성능 저하가 발생을 한다 비동기식으로 사용을 하는데 그냥 이벤트로 콜백 걸어 놓고 OS 한테 야! 연결 신호오면 알려줘 하고 쓰레드는 다른 일하러 갑니다. CONNECT 신호가 오면 OS가 인력사무소(쓰레드 풀)에 알려주고 대기 하고 있는 쓰레드 아무나 가서 해당 일 처리를 한다. 이정도로 이해하면 되는지 여쭤보고 Q2. 서버 공부를 할 때 이해를 기반으로 시간날때마다 손으로 쳐보면서 익숙해지도록 해두면서 공부하는 것이 좋나요? 나중가서 실무에서 업무를 맡게되면(물론 저는 컨텐츠 플머 지망이지만) 선생님께서 수업하실 때 하는 것처럼 머리속에서 바로바로 나오게 할려면 외워야 할텐데.. 개념은 당연히 남에게 설명할 정도로 숙지를 해야겠지만 직접 짜보라고 하면,, 못할거 같아서요 ㅠ.ㅠ 실무 경험도 없고 신입 기준 네트워크 프로그래밍 공부 방법 좀 알려주시면 정말 감사하겠습니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 선생님 수업 예제 코드에 대해서 질문 드립니다.
메인 함수 내부 Task t1 = new Task(Thread_1); Task t2 = new Task(Thread_2); t1.Start(); // 조금만 시간을 맞물리게 하면 데드락이 해결될 수 있다 Thread.Sleep(100); // 0.1 초후에 t2이 시작된다를 강제함 t2.Start(); Q1 ) 이 코드에서 이전 강의 질문의 연장선상이지만 Task는 일감이라고 하셨고, 일감 두개 t1,t2가 생성이 되었고, 2개니까 쓰레드 풀에서 쓰레드 2개를 뽑아다가 개별 쓰레드에게 하나씩 맡기는 구조인가요? Q2 )쓰래드 풀에서 A쓰레드 B쓰레드를 뽑아다가 A 쓰레드에게 t1 일감을 맡기고, B 쓰레드에게 t2 일감을 맡기고 아까 Thread.Sleep의 주체가 누구인지 여쭤봤는데 이 코드만 보면 t1. start() 코드 밑에 Thread,sleep 이 있으니까 t1을 재우는 것을 직관적으로 알수가 있는데, thread,sleep을 사용하는게 주체가 따로 없이 이 함수를 호출하기 전의 쓰레드 전부를 재우는 것인지 궁금합니다. 즉, 쓰레드 슬립의 정확한 사용법을 알고 싶습니다. 감사합니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 선생님 Task 에 대해서 또다시 질문드립니다
Task t = new Task(ThreadMain); t.Start(); // 쓰레드 풀에 있던 쓰레드를 이용해서 일감을 받아서 실행 Thread.Sleep(1000);// 메인 쓰레드가 잠든다. 위 코드는 선생님에서 수업시간에 하셧던거 모르는 부분 발췌 한 것입니다. Q1. 여기서 쓰레드 풀을 따로 생성하지 않으셨는데 설명 하실때 쓰레드 풀에 있던 쓰레드를 이용해서 일감을 받아서 실행 한다고 하셨습니다. -> 현재 코드에는 쓰레드풀을 생성하시지 않으셨고 (앞전 수업처럼 쓰레드풀 MIN,MAX 함수 써서 쓰레드 풀의 쓰레드는 최소 몇개 최대 몇개 설정 하심) 그냥 Task만 사용하셨습니다. 그럼 디폴트 쓰레드 풀이 내장되어 있는 것입니까? 디폴트 쓰레드 풀이 있다고 한다면 그 쓰레드 풀은 쓰레드가 몇개가 대기중입니까? Q2. 그 다음 줄에 메인 쓰레드가 잠드는 즉, TASK (일감) -> ThreadMain함수를 실행하는 일감 을 맡은 쓰레드가 해당 함수를 실행할 시간을 벌기 위해서 Thread.Sleep(1000); 으로 메인 쓰레드를 재운다 라고 하셨는데 뒷 강의 에서도 Thread.Sleep과 yeild 이런 것이 나오는데 이놈들의 주체는 누구입니까? 메인 함수를 맡은 쓰레드를 메인 쓰레드라고 부르시는 것 같은 데, Main() 함수 내부에서 Thread.sleep을 사용하면 main함수 내부에서 사용했으니까 메인 쓰레드를 재우는 것인가요???? 어제 멀티 쓰레드 부분 쪽은 완강하고 네플 나가기 전에 복습 하고 있는데 몇 개 헷갈린 부분이 있어서 질문드립니다 즐거운 설날 되세요 ~!!감사합니다 선생님
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 선생님 Thread.Yeild(); 에 대해서 질문 합니다.
while(true) { int expected = 0; int desired = 1; if (Interlocked.CompareExchange(ref _locked, desired, expected) == expected) break; Thread.Yield(); } 이 코드를 정리를 해보면 만약에 A 쓰레드가 있고, B쓰레드가 있다 A쓰레드가 공유 자원을 점유하고 있으면 lock이 0에서 1로 바뀌고 B 쓰레드는 접근 하려니까 lock이 1이니까 계속 무한 루프를 돈다. 이것은 성능상의 저하를 불러 일으킨다. 왜? 쓸데없는 행동이기 때문에 따라서 A쓰레드가 공유자원을 사용을 끝날 때 까지 B쓰레드를 무한루프를 돌게 하지말고 재우는데 Thread.sleep, yeild.. 뭐 이런 함수를 이용해서 재우는데 그럼 무한 루프가 잠시 멈추는 상황이잖아요? 그럼 a쓰레드가 공유자원을 쓰고 나왔다는 것을 어떻게 알 수 있나요? 검색 해보니까 sleep을 os가 깨운다는데 그럼 정리를 해보면 면접관님 께서 만약 이런 질문을 하시면 일단 OS가 A 쓰레드가 할일을 끝냈으니, 잠자고 있던 B쓰레드를 깨워서 그때부터 반복을 해서 다시 LOCK 검사를 진행합니다. LOCK 변수 값이 0이라면 컨텍스트 스위칭이 일어나는데 A 쓰레드의 정보가 레지스터에서 지워지고 B 쓰레드 정보가 채워짐으로써 B 쓰레드가 CPU를 점유하고 이제 B쓰레드가 공유자원 _num변수를 사용해서 _num++연산이 진행이 됩니다. 이렇게 저는 해당 챕터 강의를 이해 하고 정리를 했거 든요 혹시 틀린 점이 있다면 알려주심 감사하겠습니다. 아 그 sleep 걸어놓고 os가 깨우는 거 맞는지도 알려주시면 감사하겠습니다. ^^
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 선생님 Task에 대해서 질문 드립니다.,
전 강의 TASK에 대한 설명 TASK는 워커 쓰레드를 소모하는 것이 아닌 별도의 쓰레드 이다. 쓰레드 풀에 들어가긴 하지만, 애당초 별도의 특이한 쓰레드여서 오래 걸리는 작업일 때, 그때 만들어 주어서 맡기는 것이라고 보면된다. 즉, 워커 쓰레드 풀에서 뽑아서 실행하는 게 아니라 별도 처리를 해주는 것 즉, 쓰레드랑 쓰레드 풀의 양쪽 장점만을 이용하는 것 -------------------- 애당초 쓰레드 풀을 사용하는 이유가 쓰레드를 생성하고 소멸하는데 많은 성능을 잡아먹기 때문에 쓰레드를 이용하고 나서 소멸시키지 않고 쓰레드 풀에 넣어놓는 재활용 개념이 이라고 알고 있는데요 질문 1, 여기서 앞선 강의에서 쓰레드를 최소 1개 최대 5개를 생성해주고 오래 걸리는 작업이 있을 때 그때 테스크를 생성해 서 걔한테 맡기면 워커 쓰레드를 사용하지 않는다. 워커 쓰레드가 아닌 별도의 쓰레드 이다 까진 이해가 가는데 쓰레드 풀 공간을 1 ~ 5까지 할당을 명시적으로 해두었는데 쓰레드 풀에 TASK가 들어가나요? 쓰레드 풀에 별도의 TASK가 들어갈 공간이 동적으로 생성이 되나요? 질문 2. 쓰레드 풀에 TASK가 들어간다면 이 강의의 예제 코드를 보면 쓰레드 풀을 생성하시지 않으셨는 데, 이해가 잘 안갑니다. 어느때 TASK를 써야하고 어느 떄 쓰레드 풀을 사용해야 하는지 ㅠ.ㅠ 비유를 하자면 한 나라의 군인들 중 관군들이 있고 (쓰레드 풀), 의병 ( TASK ) 가 있는데, 외적이 쳐들어 왔습니다. 관군들을 소모 시키고 싶지 않아서 그때 마다 외적이 좀 빡셀거 같으면 그때마다 의병( TASK)를 이용하고 관군들을 채용하고 훈련시키는 비용이 꽤 많이 들고 이들을 소모 시키기엔 재정적으로 문제가 있으니까 빡센 일이 닥쳤을 때는 의병(TASK)를 세운다 얘가 죽건 말건 상관없이 버리는 카드 즉, 의병(TASK)의 소속은 A라는 나라(쓰레드 풀) 이지만 정식 군인 (쓰레드)가 아니다. 이런 개념인거 같은데 질문이 좀 길어졌는데, 쓰레드 풀을 생성하지 않고 별도로 TASK를 사용을 하는지 그럼 TASK는 쓰레드 풀에 소속된 것이 아니라는 얘기인데 언제 쓰레드풀을 사용하고 언제 TASK를 사용하는지 여쭤봅니다
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Interlocked.Exchange 대신 lock 사용
Session#1 강의 중 Disconnect()에서 멀티쓰레드 환경으로 인해 Interlocked를 사용을 하셨는데 이전에 배웠던 lock 구문을 통해 사용해도 되는거죠? 궁금한게 둘다 동기화 목적으로 쓰는 방식으로 아는데 어떨땐 interlock을 쓰고 어떨땐 lock 키워드를 쓰는지 궁금합니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
OnRecvCompeleted 의 null param
OnRecvCompeleted(null, recvArgs); 여기에서 sender에 null 을 넣어주는 것이 잘 이해가 되지 않습니다..
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
13:38 ReaderWriterLock 질문입니다.
강사님께서 아무도 WriteLock을 잡고있지 않다면, Lock이 없는 것처럼 동시다발적으로 들어온다고 하셨는데요. WriteLock를 잡았을 때, Lock이 없는 것처럼 행동하던 GetRewardById를 잡고있는 스레드들은 어떻게 처리되나요? 여러 스레드가 lock이없는 것처럼 들어오다가, 어떤 스레드가 WriteLock을 잡으면 서로 배타적으로 잠금된다는게 이해가 힘듭니다 ㅜㅜ
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
강사님. API 학습에 대해서 여쭤보고 싶습니다.
학습을 해 나갈 수록 점점 더 많은 기능들을 만나는 거 같아요. 제가 코딩 경험이 부족해서 많은 API들을 학습하는 것에 있어서 어떤식으로 접근해야 하는지 여쭤보고 싶습니다. 그때그때 필요한 API들을 찾아내야 될거같은데... API만 따로 학습한 뒤에 프로젝트에 적용하시는 편이신지 아니면 API들을 많이 사용하다 보니 자연스럽게 외워지신건지 궁금합니다... 또 어떤식으로 학습하시는 걸 좋아하는 지도 여쭤보고싶어요!!
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
이동 동기화들을 보면서 생각한게 있는데요.
만약에 애니메이션 이나 따로 동기화 하는 부분이라면 애니메이션 동기화를 예를들면, 파라미터 데이터를 하나씩 보내는거 보다는 한 캐릭터에 모든 파라미터 데이터를 모았다가 한번에 서버로 보내는게 최고에 방법인가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
15분 근처부터 Session을 매개변수로 받는 부분
class PacketHandler { public static void PlayerInfoReqHandler(PacketSession session, IPacket packet) { PlayerInfoReq p = packet as PlayerInfoReq; Console.WriteLine($"PlayerInfoReq : {p.playerId} : {p.name}"); foreach (PlayerInfoReq.Skill skill in p.skills) Console.WriteLine($"Skill({skill.id})({skill.level})({skill.duration})"); } } 위 함수에서 Session을 받아오지만 직접 사용은 하지 않는 이유가 뭔가요? 그냥 공통 인터페이스를 만들어놓은건가요? 그리고 굳이 IPacket으로 받아와서 PlayerInfoReq로 캐스팅하는 부분이 잘 이해가 안가는데 캐스팅 해주는 이유를 알고싶습니다.