私はクライアントサーバーアプリケーションに取り組んでいます。両側に 2 つのスレッドがあります (私が呼び出すメイン スレッドと制御スレッド)。両方のスレッドで pselect() を使用しています。コントロール スレッドの仕事は、コントロール/シグナル パケットをクライアント側のコントロール スレッドに送信して、シグナルに基づいたアクティビティを実行することです。メインスレッドの仕事は、制御スレッドが別の TCP -IPV4 接続を介して通信するときに、データを継続的に読み書きすることです。サーバー側で sigusr 信号を使用して、(mutex を使用して) いくつかのグローバルフラグを設定し、それに基づいてサーバー制御スレッド次に、シグナル パケットをクライアント側の制御スレッドに送信します。
問題: サーバーがデータを送信したことはわかります (send の戻り値を確認しています) が、クライアント側の制御スレッドの pselect() が時間どおりにそれを認識していません。 over main thread is complete) またはまったく受信しない . 別のLinuxサーバーで実行すると同じコードが正常に動作します(2.6.18-274.12.1.el5 #1 SMP Tue Nov 8 21:37:35 EST 2011 x86_64 x86_64 x86_64 GNU/Linux)が、現在のもの(2.6)では機能しません.32-220.4.2.el6.x86_64 #1 SMP Mon Feb 6 16:39:28 EST 2012 x86_64 x86_64 x86_64 GNU/Linux)
両方のサーバーの優先順位とスケジューリング スキームは同じ (0,0) です。pselect を使用する前にシグナルをマスキングするために sigproc を使用して abt を読みましたが、クライアントではなくサーバーにシグナルを送るだけなので、どのシグナルを処理すればよいかわかりません。また、クライアントとサーバーの両方が同じマシンで実行されていることを追加します(通信にループバックアドレスを使用しています)。ブロッキング (pselect の時間構造体が NULL に設定されている) と pselect の非ブロッキング モードの両方を試しました。また、毎回ループで FD_SET にソケット ID を設定しています。ご意見をお聞かせください
/ * ***コード** * * /
while(vg_closeCtrlThread==0)
{
FD_ZERO(&vl_fdsctrl);
FD_SET(vg_ctrlSocket.socket_id,&vl_fdsctrl);
//fprintf(stdout,"Setting FD SET...Control thread \n");
/* Set the select polling to few seconds */
vl_tv.tv_sec = 0;//HS
//vl_tv.tv_sec = 50;//HS
vl_tv.tv_nsec = 10000;
/* Set the select polling to few seconds */
vl_tv2.tv_sec = 0;//HS
vl_tv2.tv_nsec = 500;
/* variable vg_ctrlpacket_sent and ip_proto_switch are set when sigusr is received for server process using mutexes , this if cond executes only on server side */
if(vg_dataSocket->vst_iptype == IPV_BOTH && vg_ctrlpacket_sent && ip_proto_switch)
{
fprintf(stdout,"vg_ctrlpacket_sent value:%d\n",vg_ctrlpacket_sent);
fprintf(stdout,"ip_proto_switch value:%d\n",ip_proto_switch);
if(vg_ctrlSocket.vst_isserver)
{
FD_ZERO(&vl_fds);
FD_SET(vg_dataSocket->sock_id[1],&vl_fds);
fprintf(stdout,"\t\t Switch protocol..Control Thread\n");
vl_ctrlInfo->vst_type = IP_SWITCH;
vlError = fn_send(&vg_ctrlSocket,(char *)&vl_ctrlInfo->vst_type,sizeof(vl_ctrlInfo->vst_type),NO_DATA_TX);
fprintf(stdout,"Ctrl packet Send error:%d\n",vlError);
if(vlError == -1)
{
fprintf(stderr,"Error in sending the data,Err:%s\n",fn_strerror_r(errno,err_buff),vg_ctrlSocket.vst_nm_thread);
exit(EXIT_FAILURE);
}
}
vg_ctrlpacket_sent = 0;
pthread_mutex_lock(&socket_mutex_2);
vg_ctrlpacket_recv = 1;
pthread_mutex_unlock(&socket_mutex_2);
}
//fprintf(stdout,"Before pselect ctrlthread..\n");
/* check if any data is available on the socket */
if(vg_ctrlSocket.vst_isserver)
vlError = pselect(vg_ctrlSocket.socket_id+1, &vl_fdsctrl,NULL, NULL, &vl_tv,NULL);
else{
fprintf(stdout,"...Here is the PROBLEM*\n");
vlError = pselect(vg_ctrlSocket.socket_id+1, &vl_fdsctrl,NULL, NULL,NULL ,NULL);
//vlError = select(vg_ctrlSocket.socket_id+1, &vl_fdsctrl,NULL, NULL,NULL);
}
//perror("Just to check for illegal error\n");
/* Reinitialize the polling to few seconds */
vl_tv.tv_sec = 0;//HS
vl_tv.tv_nsec = 10000;
if(vlError == -1)
{
perror("Error in select() function of Control thread");
exit(EXIT_FAILURE);//HS
}
else if(vlError > 0)
{
memset(vlBuffer,0,56);
if(debug>1){
fprintf(stdout,"The socket id is:%d, Thread:%s\n",vg_ctrlSocket.socket_id,vg_ctrlSocket.vst_nm_thread);
}
vlError = fn_recv(&vg_ctrlSocket,(char *)&vl_ctrlInfo->vst_type,sizeof(vl_ctrlInfo->vst_type),NO_DATA_TX);
if(vlError < 0)
{
fprintf(stderr,"Error in receiving the data,Err:%s\n",fn_strerror_r(errno,err_buff));
exit(EXIT_FAILURE);
}
if(vlError > 0)
{
if(debug>1)
fprintf(stdout,"Some data received: %d, Thread:%s..\n",vlError,vg_ctrlSocket.vst_nm_thread);
switch(vl_ctrlInfo->vst_type)
{
case BANDWIDTH_INFO:
if(debug)
fprintf(stdout,"Received bandwidth information..Control Thread\n");
vlError = fn_recv(&vg_ctrlSocket,(char *)&vl_ctrlInfo->vst_info,sizeof(vl_ctrlInfo->vst_info),NO_DATA_TX);
fprintf(stdout,"Bandwidth :%.3f\n",vl_ctrlInfo->vst_info.vst_info);
if(vlError > 0)
fn_setShmDownStreamInfo(vl_ctrlInfo->vst_info);
break;
case PROTO_ACK_INFO:
fprintf(stdout,"Received ack..Control Thread\n");
vlError = fn_recv(&vg_ctrlSocket,(char *)vl_ctrlInfo,sizeof(st_ackPacket),NO_DATA_TX);
if(vlError > 0)
fn_protoProcessAck(vlBuffer);
break;
case IP_SWITCH:/* this is packet data for now */
fprintf(stdout,"\t\t switch..Control Thread\n");
pthread_mutex_lock(&socket_mutex_2);
fprintf(stdout,"Locking vg_ctrlpacket_recv..Control Thread\n");
vg_ctrlpacket_recv = 1;
pthread_mutex_unlock(&socket_mutex_2);
break;
} /* switch(vl_ctrlInfo->vst_type) */
} /* if(vlError > 0) */
else if(vlError == 0)
{
fn_cleanUpCtrlThread();
}/* if(vlError == 0) */
}/* if(vlError) */
}/* while(vg_closeCtrlThread==0) */
ありがとう...