Photonでのマルチスレッド

記事の内容はなんですか

この記事では、サーバー側のマルチスレッドについて説明します。





  • どのように実装されていますか





  • 使用方法





  • 何ができるか





  • 私たち自身が発明したもの





これらの質問はすべて、サーバー側で直接何かを開発している場合にのみ関係します。SDKコードを変更したり、独自のプラグインを作成したり、独自のことをしたりする場合です。





Photonはマルチスレッドをどのように処理しますか?

フォトンサーバーアプリケーションは、複数のクライアント接続からの要求を受け入れます。そのような接続をピアと呼びますこれらの要求はキューを形成します。饗宴ごとに1つ。ピアが同じルームに接続されている場合、それらのキューは1つに結合されます(ルームキュー)。そのような部屋は最大で数千あり、それらの要求キューも並行して処理されます。





Photonでのタスクキューの実装の基礎として、Jetlangライブラリに基づいて開発されたretlangライブラリが採用されました。





Taskとasync / awaitを使用しない理由

したがって、次の考慮事項があります。





  1. これらのものが現れる前に、フォトンは発達し始めました。





  2. , , - . , , , GC , . , .





  3. TaskScheduler, , - .





Fiber?

, . - FIFO. , multiple writers-single reader. , , , .. . .





Photon , PoolFiber, . IFiber. .





  • ThreadFiber - IFiber, . .





  • PoolFiber - IFiber, .NET. . . ( ).





  • FormFiber/DispatchFiber - IFiber, WinForms/WPF. FormFiber/DispatchFiber Invoke BeginInvoke .





  • StubFiber - . , (races) . .





PoolFiber

PoolFiber. , . :





  1. . ThreadPool.QueueUserWorkItem. - .





  2. , , ThreadPool.QueueUserWorkItem, . . , .





.. , , . , , () . - , , .





PoolFiber

Photon PoolFiber. , . , , . .. PoolFiber.Stop . .





. -. , , , .





:









  • ,





  • , .





:





//    
fiber.Enqueue(()=>{some action code;});

      
      



//    ,    10 
var scheduledAction = fiber.Schedule(()=>{some action code;}, 10_000);
...
//  
scheduledAction.Dispose()

      
      



//    ,    10    5
var scheduledAction = fiber.Schedule(()=>{some action code;}, 10_000, 5_000);
...
//  
scheduledAction.Dispose()

      
      



, - , fiber.Schedule. .





Executors

. , . Execute(Action a)



Execute(List<Action> a)



. PoolFiber . .. . . DefaultExecutor. :





        public void Execute(List<Action> toExecute)
        {
            foreach (var action in toExecute)
            {
                Execute(action);
            }
        }

        public void Execute(Action toExecute)
        {
            if (_running)
            {
                toExecute();
            }
        }

      
      



. 'action' toExecute . FailSafeBatchExecutor, try/catch. , . , , github.





BeforeAfterExecutor

, . BeforeAfterExecutor. "" . , FailSafeBatchExecutor. BeforeAfterExecutor . :





public BeforeAfterExecutor(Action beforeExecute, Action afterExecute, IExecutor executor = null)

      
      



. . . / , , . , .





:






var beforeAction = ()=>
{
  log4net.ThreadContext.Properties["Meta1"] = "value";
};

var afterAction = () => ThreadContext.Properties.Clear();

// 
var e = new BeforeAfterExecutor(beforeAction, afterAction);

// PoolFiber
var fiber = new PoolFiber(e);

      
      



- , fiber, log4net Meta1 value.





ExtendedPoolFiber ExtendedFailSafeExecutor

, retlang, . . , . . PoolFiber ( , .NET). , , HTTP . :





  1. event;





  2. , , , , event ;





  3. event.





. , , , , event. . . , .





ExtendedPoolFiber ExtendedFailSafeExecutor. . , . , Pause. ( ) . :





  1. Resume





  2. ( Pause) Resume , , .





, , HTTP . , . Resume , .





, ThreadFiber .





IFiberAction

IFiberAction - GC. .NET. , IFiberAction. , . GC





IFiberAction :





public interface IFiberAction
{
    void Execute()
    void Return()
}
      
      



Execute , . Return Execute, .





:





public class PeerHandleRequestAction : IFiberAction
{
    public static readonly ObjectPool<PeerHandleRequestAction> Pool = initialization;
    public OperationRequest Request {get; set;}
    public PhotonPeer Peer {get; set;}
    
    public void Execute()
    {
        this.Peer.HandleRequest(this.Request);
    }
    
    public void Return()
    {
        this.Peer = null;
        this.Request = null;
        
        Pool.Return(this);
    }
}

//     

var action = PeerHandleRequestAction.Pool.Get();
action.Peer = peer;
action.Request = request;

peer.Fiber.Enqueue(action);

      
      



, . , . , PoolFiber . PoolFiber .NET. PoolFiber , . , ExtendedPoolFiber.





IExecutorインターフェイスを実装するエグゼキュータは、ファイバーでのタスクの実行に直接関与ますDefaultExecutorはすべての人に適していますが、例外が発生した場合、実行のために転送された残りのタスク全体が失われます。FailSafeExecutor は、この点で賢明な選択のようです。エグゼキュータによるタスクのバッチの実行の前後に何らかのアクションを実行する必要がある場合は、BeforeAfterExecutor役立ちます。








All Articles