日期:2014-05-16 浏览次数:20721 次
问题描述:
程序本意是来一个客户端连接就创建一个线程与其通信,并判断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);