반응형

Thrift를 현재 회사에서 사용하고 있는데 생각외로 문서나 포스팅이 없어서 간단하게 포스팅을 해본다

 

우선 Thrfit란 무엇인가?

 

thrift는 facebook에서 개발하고 현재는 Apache 재단에 의해서 관리, 개발되고 있는 라이브러리이다.

 

거두절미하고 장점과 단점을 말해보면,

 

우선 장점으로는 각기 다른 개발언어의 프로그램끼리 공통 RPC를 통해 통신할 수 있다는 점이 있고

반면 단점으로는 RPC관련 생성파일들의 코드가 매우 지저분하다는 점이다.

 

비슷한 RPC관련 라이브러리로 Google Protocol Buffer 라는게 있는것 같은데 여기서는 다루지 않겠다.

 

해당 라이브러리 다운로드 주소 : https://thrift.apache.org/download

 

Apache Thrift - Download

Release The latest stable release of Thrift is 0.13.0 (released on 2019-OCT-16). Maven artifact org.apache.thrift libthrift 0.13.0 When downloading from a mirror, please be sure to verify the checksums and signature (see the MD5 and PGP links above). The K

thrift.apache.org

위 주소에 가면 thrift-0.13.0.tar.gz 파일과 Thrift compiler for Windows (thrift-0.13.0.exe) 파일을 다운로드 받을 수 있다.

thrift-0.13.0 파일의 경우 압축을 해제해보면 tutorial 폴더 외 여러 폴더가 보이는데 우리는 C#만 사용할 것이기 때문에 

thrift-0.13.0\lib\csharp\src 에 있는 파일들을 별도 프로젝트에 복사해 사용할 것이다.

 

thrift-0.13.0.exe 파일의 경우는 xxx.thrift 문서 파일에 명시된 정보들을 통해 RPC와 관련된 파일을 생성해준다.

 
struct SharedStruct {
  1: i32 key
  2: string value
}
 
 
 service RPCTest
 {
 	i32 sendPing(),
    void sendPing2(),
    oneway NotiTest(),
 }

위 처럼 단순 struct부터 RPC인 service, 한방향 호출 RPC[리턴값이 oneway인 것] 까지 필요에 맞게 정의하면 된다.

 

그리고 thrift.exe 파일의 경우 우리가 추가적으로 thrift-0.13.0\compiler\cpp\compiler.sln을 통해서

 

추가타입 혹은 코드 변경을 통해서 커스터마이징 후 빌드하여 사용할 수 있게 되어 있다.

 

해당 exe 파일을 실행 시 매개변수로 몆가지 명령어를 같이 넣어줄 수 있는데

 

-out, --gen 명령어만 알아두어도 기능 테스트에는 충분할 것이다.

 

우선 -out 의 경우 우리가 thrift에 정의한 RPC 규격에 대한 cs파일이 위치할 폴더의 경로를 지정할 수 있다.

ex : -out ..\..\thrift\RPC

 

--gen의 경우 해당 RPC규격파일에 따른 코드를 생성 하기 위해서 어떠한 언어인지, 참고할 thrift 파일은 어디에 있는지를 지정해준다.

ex : --gen csharp:async .\TestRPC.thrift

 

Tip - 

해당 thrift.exe. 파일의 경우 일일히 cmd 창등을 통해 실행하기 귀찮기 때문에 bat파일을 활용하면 좋다.

 

 

 

 

 

반응형

'Network' 카테고리의 다른 글

HTTP Protocol  (0) 2021.06.20
OSI 7계층과 TCP/IP 4 계층  (0) 2021.06.20
load balancing  (0) 2020.08.27
OSI 7계층와 TCP/IP 4 계층  (0) 2020.08.27
RabbitMQ에 대해서  (0) 2019.07.21
Posted by Sweetmeats_boy
반응형

출처 : MSDN : https://docs.microsoft.com/ko-kr/dotnet/standard/threading/cancellation-in-managed-threads

 

관리되는 스레드의 취소

관리되는 스레드의 취소Cancellation in Managed Threads 이 문서의 내용 --> .NET Framework 4부터 .NET Framework에서는 비동기 또는 장기 실행 비동기 작업의 협조적 취소를 위한 통합 모델을 사용합니다.Starting with the .NET Framework 4, the .NET Framework uses a unified model for cooperative cancellation of asynchron

docs.microsoft.com

우리가 비동기 함수를 호출할 때 가령 socket의 accept를 비동기로 호출한 후

서버 가동을 중지할 때 해당 Accept를 중지하는 경우 등등 해당 비동기 함수에 대하여

작업을 취소해야하는 경우가 있을 수 있다.

 

이런 경우 해당 함수에 대하여 직접적인 접근을 할 수도 있겠지만

단순히 중지를 알림으로써 해결할 수도 있을 것이다.

이와 관련하여 사용할 수 있는것이 CancellationTokenSource와 CancellationToken이다.

 

이해한 바에 따르면 우선 Token의 경우 구조체이기 때문에 값복사가 이루어진다.

이러한 토큰은 TokenSource의 인스턴스가 제공하는 CancellationTokenSource.Token의 반환값을 사용하며,

이 token을 각각의 "취소요청을 수신할 스레드"에 전달한다.

물론 위의 스레드, 작업(Task)의 경우 token이 최소된 경우 처리할 로직을 구현해야한다.

더불어 만약 TokenSource가 Token외 별도의 리소스를 지닌 상태라면

해당 리소스에 관한 처리도 Dispose에서 처리해줘야 한다.

 

MSDN에서 제공한 소스코드 예제를 보자.

using System;
using System.Threading;

public class Example
{
   public static void Main()
   {
      // Create the token source.
      CancellationTokenSource cts = new CancellationTokenSource();

      // Pass the token to the cancelable operation.
      ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomeWork), cts.Token);
      Thread.Sleep(2500);

      // Request cancellation.
      cts.Cancel();
      Console.WriteLine("Cancellation set in token source...");
      Thread.Sleep(2500);
      // Cancellation should have happened, so call Dispose.
      cts.Dispose();
   }

   // Thread 2: The listener
   static void DoSomeWork(object obj)
   {
      CancellationToken token = (CancellationToken)obj;

      for (int i = 0; i < 100000; i++) {
         if (token.IsCancellationRequested)
         {
            Console.WriteLine("In iteration {0}, cancellation has been requested...",
                              i + 1);
            // Perform cleanup if necessary.
            //...
            // Terminate the operation.
            break;
         }
         // Simulate some work.
         Thread.SpinWait(500000);
      }
   }
}
// The example displays output like the following:
//       Cancellation set in token source...
//       In iteration 1430, cancellation has been requested...

위에서 보이듯이 TokenSource인 cst가 cancel함수를 호출한 경우

DoSomeWork의 인자로 들어간 token의 IsCancellationRequest가 바뀐다.

이 때 token이 IsCancellationRequested가 한번 true로 변경될 시 다시 false로 바꿀 수 없다.

 

또 다른 활용법으로는 취소 요청이 호출된 순간에 처리할 작업을 지정하는것도 가능하다.

using System;
using System.Threading;

class CancelableObject
{
   public string id;
   
   public CancelableObject(string id)
   {
      this.id = id;
   }
   
   public void Cancel() 
   { 
      Console.WriteLine("Object {0} Cancel callback", id);
      // Perform object cancellation here.
   }
}

public class Example
{
   public static void Main()
   {
      CancellationTokenSource cts = new CancellationTokenSource();
      CancellationToken token = cts.Token;

      // User defined Class with its own method for cancellation
      var obj1 = new CancelableObject("1");
      var obj2 = new CancelableObject("2");
      var obj3 = new CancelableObject("3");

      // Register the object's cancel method with the token's
      // cancellation request.
      token.Register(() => obj1.Cancel());
      token.Register(() => obj2.Cancel());
      token.Register(() => obj3.Cancel());

      // Request cancellation on the token.
      cts.Cancel();
      // Call Dispose when we're done with the CancellationTokenSource.
      cts.Dispose();
   }
}
// The example displays the following output:
//       Object 3 Cancel callback
//       Object 2 Cancel callback
//       Object 1 Cancel callback

위 코드에서 보이듯이 해당 token에 Register 함수를 통해 token에 취소 요청이 올 경우 처리할 작업을 등록할 수 있다.

 

이 외에 Exception 을 활용한 방법도 존재하며 이방법에 대해서는 아래의 링크를 참고하면 된다.

https://docs.microsoft.com/ko-kr/dotnet/standard/parallel-programming/task-cancellation

 

작업 취소

작업 취소Task Cancellation 이 문서의 내용 --> System.Threading.Tasks.Task 및 System.Threading.Tasks.Task 클래스는 .NET Framework에서 취소 토큰을 사용하는 방법으로 취소 기능을 지원합니다. The System.Threading.Tasks.Task and System.Threading.Tasks.Task classes support cancellation through the use

docs.microsoft.com

 

 

반응형

'개발언어 > C#' 카테고리의 다른 글

Thread와 Task  (0) 2021.06.20
ThreadStatic 과 ThreadLocal  (0) 2019.11.28
알아두면 어쩌다 쓸것같은 Attribute들-1  (0) 2019.09.05
async, await란  (0) 2019.08.11
Posted by Sweetmeats_boy
반응형

ThreadStatic과 ThreadLocal의 역할은 각 스레드가 고유한 변수를 지니게 만드는 것이다.

 

다만 약간의 차이가 있으며 그 사항은 아래와 같다.

1. ThreadStatic의 경우 전역  변수에 한해서 사용 가능하다.

2. ThreadStatic에 초기값을 설정할 시 모든 스레드가 기본 초기값으로만 초기화가 된다.

 

[ThreadStatic]
public static int staticVal = 10;


public void int Main()
{
	staticVal = 25;
    
    Thread t1 = new Thread(()=>{
    	Console.WriteLine(staticVal);
    });
    staticVal = 50;
    Thread t2 = new Thread(()=>{
    	Console.WriteLine(staticVal);
    });
    staticVal = 100;
    Thread t3 = new Thread(()=>{
    	Console.WriteLine(staticVal);
    });
}

대충 위와 같은 코드가 존재할 시 각 출력함수들은 모두 10을 출력하게 된다.

이유는 Main함수가 속한 Thread에서의 staticValue값과 t1, t2, t3에서의 staticValue 값은 별개이기 때문이다.

 

ThreadLocal의 경우 ThreadStatic과 같이 각 스레드에 속한 고유 변수를 만들 때 사용한다.

다만 차이점으로는 ThreadStatic과 달리 초기값지정이 가능하다는 것과 전역변수일 필요가 없다는 점이다.

 

public void Main()
{
	ThreadLocal<int> tId = new ThreadLocal<int>(()=>{
    	return Thread.CurrentThread.ManagedThreadId;
    });
    
    Thread t1 = new Thread(()=>{
    	Console.WriteLine("tid : "+tId);
    });
    Thread t2 = new Thread(()=>{
    	Console.WriteLine("tid : "+tId);
    });
    Thread t3 = new Thread(()=>{
    	Console.WriteLine("tid : "+tId);
    });
}

대충 위와 같은 코드의 경우 t1~t3은 각각 생성된 Thread의 id 값으로 초기화가 된다.

 

간단하게 게임등에서 사용하는 경우로는 random과 관련된 로직이 있다.

단순 random의 경우 단순 시간정보로 시드를 대입하면 모든 스레드에서 동일한 값이 추출되지만

이 시드값에 위의 코드처럼 각 스레드의 고유한 값을 조합한다면 모두 다른 랜덤값이 추출될 것이다.

 

다만 ThreadLocal의 경우 .Net 4.0 부터 추가됐기 때문에 버전을 고려해서 사용해야 한다.

ThreadLocal<Random> tRand = new ThreadLocal(()=>{
	return new Random();
});

ThreadLocal<Random> tRand2 = new ThreadLocal(()=>{
	return new Random(Thread.CurrentThreadId + something);
});

위 코드 둘다 각 스레드 고유의 랜덤을 생성해서 반환하지만 

tRand의 경우 만약 다른 두 스레드의 초기화 시간이 미미한 차이라면 같은 Random분포를 지니게 된다.

tRand2의 경우처럼 스레드 개별 정보를 추가해서 구분해준다면 모든 스레드의 Random객체는 다른 분포를 지니게 될 것이다.

 

반응형

'개발언어 > C#' 카테고리의 다른 글

Thread와 Task  (0) 2021.06.20
CancellationTokenSource 과 CancellationToken  (0) 2019.11.29
알아두면 어쩌다 쓸것같은 Attribute들-1  (0) 2019.09.05
async, await란  (0) 2019.08.11
Posted by Sweetmeats_boy

블로그 이미지
Sweetmeats_boy

태그목록

Yesterday
Today
Total

달력

 « |  » 2024.11
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함