linux下多线程服务器处理程序有关问题解决
问题描述:
程序本意是来一个客户端连接就创建一个线程与其通信,并判断5秒内如无数据接收则断开连接,关闭网络描述符与回收线程资源。
但是结果则不尽人意,运行了一段时间后,通过cd /proc/PID/ 查看里面的内容,线程已经消失,但其资源未释放,后通过查看代码,怀疑是主线程传递给子线程的网络描述符未进行互斥保护,导致传递给子线程的网络描述符出差错。
原因:
主线程在使用pthread_create创建线程时,如果pthread_create 函数的第四个参数(指针参数)传入的值会被主线程随时修改时,这时我们的线程从pthread_create 函数的第四个参数获取的值可能就不是我们想要传入的值了。
原代码与改进后的代码(增加红色部分)
/*
功能 : 创建TCP网络套接字
参数1 : 端口号
参数2 : IP地址
返回值: 整型(成功返回0,失败返回-1)
*/
int Create_Tcp_Socket(short port,char *ipv4address)
{
int reuser = 1;
int listenSock,acceptSock;
struct sockaddr_in caddr;
socklen_t length;
int result;
pthread_t *pthreadId ;
pthreadId = malloc(sizeof(pthread_t)*10);
pthread_mutex_init(&m_Locker,NULL); // 初始化互斥锁
pthread_mutex_init(&lock,NULL);
pthread_cond_init(&m_Cond,NULL);
fd_set allNetSock;
FD_ZERO(&allNetSock);
if(-1 == (listenSock = socket(AF_INET,SOCK_STREAM,0)))
{
perror("create listeSock failed\n");
return -1;
}
setsockopt(listenSock,SOL_SOCKET,SO_REUSEADDR,&reuser,sizeof(reuser));
if(-1 == (mybind(listenSock,port,ipv4address)))
{
perror("bind failed\n");
return -1;
}
printf("bind sucessed!\n");
if(-1 == listen(listenSock,10))
{
perror("listen failed\n");
return -1;
}
while(1)
{
length = sizeof(struct sockaddr_in );
pthread_mutex_lock(&m_Locker); // 申请互斥锁
if(-1 == (acceptSock = accept(listenSock,(struct sockaddr*)&caddr,&length)))
{
perror("accept failed\n");
sleep(1);
continue;
}
else
{
if( 0 != (result = pthread_create((pthreadId + (acceptSock - 4)),NULL,(void*)different_client_pthread_handle_fun,&acceptSock)))
{
perror("child pthread failed\n");
exit(1);
}
pthread_t tid;
tid = pthread_self();
printf("main thread is %u\n",(unsigned int )tid );
pthread_detach(*(pthreadId + (acceptSock - 4)));
}
pthread_cond_wait(&m_Cond,&m_Locker); // 用于阻塞线程,等待其它线程释放m_Locker锁。
pthread_mutex_unlock(&m_Locker); // 释放互斥锁
/*
FD_SET(acceptSock,&allNetSock);
if(1)
driving_send_alarm_info(&allNetSock);
*/
}
close(listenSock);
free(pthreadId);
}
/*
功能 : 处理不同客户端线程服务函数
参数1 : 网络描述符
返回值: 无
*/
void* different_client_pthread_handle_fun(void *arg)
{
pthread_mutex_lock(&m_Locker); // 申请互斥锁
int fd = *(int*)arg;
printf("fd is %d\n",fd);
pthread_cond_signal(&m_Cond); // 发送信号给主线程,使其对m_Locker的拥有
pthread_mutex_unlock(&m_Locker); // 释放互斥锁
pthread_t tid;
tid = pthread_self();
printf("child thread is %u\n",(unsigned int )tid );
int result;
fd_set readfds;
struct timeval tv;
FD_ZERO(&readfds);
FD_SET(fd,&readfds);
while(1)
{
}
}