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