0

POSIX 共有メモリと名前のないセマフォを使用してクライアント サーバーを実装しています。サーバーは、複数のクライアントを同時に処理することが期待されています。コードは単一のクライアントでは機能しますが、複数のクライアントでは機能しません。POSIX 操作は、以下で管理されます。

enum { MAX_MSG = 256 };
enum { CLIENT_SEM,          // semaphore is 1 if server is available for use by client    
       MSG_FOR_DAEMON_SEM,  // semaphore is 1 if shm contains msg for daemon    
       MSG_FOR_CLIENT_SEM,  // semaphore is 1 if shm contains msg for client    
       MSG_FOR_SERVER_SEM,  // semaphore is 1 if shm contains msg for server    
       N_SEMS };

typedef struct {    
    sem_t  sems[N_SEMS]; // semaphore sent for sync   
    pid_t  clientPid;    // pid of current client    
    char   msg[MAX_MSG]; // current message being sent    
    int    max_matrix_size; //max rows a square matrix can have 
}Comm;

// server calls setup_comm with doCreate=1 and creates shared mem of size max_clients * sizeof(Comm) 
// client calls setup_comm with doCreate=0 and in return gets the mmap pointer to the shared memory created by the server 
Comm* setup_comm(const char *shmPosixName, int doCreate, int max_clients);

問題は、複数のクライアントを処理するために、Comm 構造の配列を維持する必要があるかどうかです。それはComm[max_clients]私が現在使用しているもの (単一の Comm 構造) の代わりですか? また、クライアントごとに、サーバーは Comm 配列を管理し、その配列から適切な要素をクライアントに返す必要があります。次に、クライアントはそのブロックを使用して、Comm 要素内のセマフォを介して操作を同期しますか? または、単一の Comm 構造で複数のクライアントを処理できますか?

4

1 に答える 1

0

Comm の単一インスタンスを使用する場合、サーバーとすべてのクライアントがその 1 つの構造体を共有して、すべての通信を行います。これは、現在アクティブなクライアントと一致するように clientPid と残りの構造体変数をシャッフルしながら、すべてのアクセスに sem_wait/sem_post を適用することを意味します。

サーバーが構造体の範囲全体を操作して、構造体の配列を割り当てる方が簡単に思えますが、各子は配列要素の 1 つだけにアクセスします (当然、それらすべてを見ることができますが、1 つしか処理しません)。次に、Comm 要素ごとのセマフォの各セットを使用して、サーバーと特定のクライアント間の通信を調整します。ここでの前提は、クライアントが相互に通信していないことです。

于 2013-11-23T18:53:00.937 に答える