我正在开发一个客户端-服务器应用程序。每边有两个线程(我调用的主线程和控制线程)。我在两个线程中都使用 pselect() 。控制线程的工作是将控制/信号包发送到客户端的控制线程,以根据信号进行活动。主线程的工作是连续读取/写入数据,控制线程通过单独的 TCP -IPV4 连接进行通信。我在服务器端使用 sigusr 信号,它设置了一些全局标志(使用互斥体)并基于该信号服务器控制线程然后将信号包发送到客户端的控制线程。
问题:我看到服务器已经发送了数据(检查发送的返回值)但是客户端控制线程中的 pselect() 没有及时识别它。我有时看到它最后接收到数据(当数据传输时over main thread 完成)或根本没有收到它。当我在不同的 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) */
谢谢...