69,371
社区成员
发帖
与我相关
我的任务
分享
void *thread_routine(void *arg)
{
T_Worker *worker = NULL;
DEBUG_PRINT("starting thread 0x%x\n",pthread_self());
while(1)
{
pthread_mutex_lock(&(gpPool->queue_lock));
while(gpPool->cur_queue_size == 0 && !gpPool->shutdown)
{
DEBUG_PRINT("thread 0x%x is waiting\n",pthread_self());
pthread_cond_wait(&(gpPool->queue_ready),&(gpPool->queue_lock));
}
if(gpPool->shutdown)
{
pthread_mutex_unlock(&(gpPool->queue_lock));
DEBUG_PRINT("thread 0x%x will exit\n",pthread_self());
pthread_exit(NULL);
}
DEBUG_PRINT("thread 0x%x is starting to work\n",pthread_self());
assert(gpPool->cur_queue_size !=0);
assert(gpPool->queue_head != NULL);
gpPool->cur_queue_size--;
worker = gpPool->queue_head;
gpPool->queue_head = worker->next;
pthread_mutex_unlock(&(gpPool->queue_lock));
(*(worker->process))(worker->arg);//此处执行pool_add_work()添加进队列的回调函数
free(worker);
worker = NULL;
}
pthread_exit(NULL);
}
gtSlot[N]是全局数组,N就是程序支持的最大的并发个数,每一路并发(就是在程序里做转换)依托一个处理句柄,这个全局数组就是保存对应的N个句柄,每一路发来的包中包含一个iID,在0~N中,由它直接定位哪一个句柄。
通过实验发现,如果Enc,Dec两个处理函数不加锁,转换出来的数据误差较大,但是加了锁会不会大大降低了效率?这两个函数是库里的,我看不到实现,本以为依托于一个处理句柄应该可重入的。我也知道这个问题问您有点不太合适,因为怎么实现的都不知道。
void *process(void *arg)
{
//arg为recvfrom得到的buffer,包含一个头和要转换的数据
PT_RcvBuf ptRcvBuf = (PT_RcvBuf)arg;
T_OutBuf tSndBuf;
short sBuf[PCM_LEN_PER_PACKET];
unsigned char ucBuf[EVRC_LOAD_LEN_PER_PACKET];
int iRet,iID;
int sendbytes = 0;
memset(&tSndBuf, 0, sizeof(T_OutBuf));
memset(&sBuf[0], 0, sizeof(sBuf));
memset(&ucBuf[0], 0, sizeof(ucBuf));
iID = (int)(ptRcvBuf->tOutBuf.tHead.ucID);
switch ( (int)(ptRcvBuf->tOutBuf.tHead.ucDirection) )
{
case ENCODE:
memcpy(&sBuf[0],ptRcvBuf->tOutBuf.ucText,ENCODE_LEN);
//编解码函数基于每一路的pHandle指针做处理,调试过程中这里有过报错,因为在lib库中,无法
//查看,所以有锁,这里略去没写
iRet = Enc(gtSlot[iSessID].pHandle, &sBuf[0], tSndBuf.ucText);//编码
if (iRet != 0)
{
printf("Enc Error!\n");
return ;
}
break;
case DECODE:
memcpy(&ucBuf[0],ptRcvBuf->tOutBuf.ucText,DECODE_LEN);
//编解码函数基于每一路的pHandle指针做处理
iRet = Dec(gtSlot[iID].pHandle, &ucBuf[0], tSndBuf.ucText);//解码
if (iRet != 0)
{
printf("Dec Error!\n");
return ;
}
break;
default:
printf("Unknown convert type: %d !\n",(int)(ptRcvBuf->tOutBuf.tHead.ucDirection));
return ;
}
memcpy( &(tSndBuf.tHead), &(ptRcvBuf->tOutBuf.tHead), sizeof(T_Head) );
//通过recvfrom把client的sockaddr结构保存下来,并在此把处理后的数据发送回这个IP及PORT
sendbytes = sendto(giSocketServer,&tSndBuf,sizeof(T_OutBuf),0,(struct sockaddr *)&(ptRcvBuf->tSocketClientAddr),giAddrLen);
if (sendbytes !=sizeof(T_OutBuf))
{
perror("sendto");
}
}