from:http://blog.csdn.net/skyflying2012/article/details/24655751及相关论坛 html
http://blog.chinaunix.net/uid-29783732-id-4485673.html linux
在写网络服务器程序时可能须要实现多线程接收多个客户端的数据,我实现方式比较傻,死循环等待client的connect,connect以后建立thread,这样其实有一个问题,服务器程序须要长期运行,长时间线程的建立,线程资源的回收就是一个问题。windows
Linux系统中程序的线程资源是有限的,表现为对于一个程序其能同时运行的线程数是有限的。而默认的条件下,一个线程结束后,其对应的资源不会被释放,因而,若是在一个程序中,反复创建线程,而线程又默认的退出,则最终线程资源耗尽,进程将再也不能创建新的线程。服务器
解决这个问题,有2种方式,系统自动释放线程资源,或者由另外一个线程释放该线程资源。网络
进程运行后,自己,也是一个线程,主线程,主线程和主线程创建的线程共享进程资源。不一样于其余线程,在于主线程运行结束后,程序退出,全部程序创建的线程也会退出。多线程
一 系统自动释放
若是想在线程结束时,由系统释放线程资源,则须要设置线程属性为detach,是线程分离主线程函数
代码上,能够这样表示:ui
pthread_t tid;
pthread_attr_t attr; //线程属性
pthread_attr_init(&attr); //初始化线程属性
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //设置线程属性
pthread_create( &tid, &attr, run, NULL); //创建线程spa
二 由另外一个线程将该资源释放.net
代码上,能够这样表示:
pthread_t t;
pthread_create( NULL, NULL, GetAndSaveAuthviewSDRStub, (void*)lp);
pthread_join( t);
pthread_join( t)等待线程t退出,并释放t线程所占用的资源。
pthread_join函数会阻塞等待指定线程退出,而后回收资源,这样就有同步的功能,使一个线程等待另外一个线程退出,而后才继续运行,可是对于服务器程序若是主线程在新建立的线程工做时还须要作别的事情,这种方法不是很好,就须要使用方法一
linux线程执行和windows不一样,pthread有两种状态joinable状态和unjoinable状态,若是线程是joinable状态,当线程函数本身返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join以后这些资源才会被释放。
如果unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。
unjoinable属性能够在pthread_create时指定,或在线程建立后在线程中pthread_detach本身,如:pthread_detach(pthread_self()),将状态改成unjoinable状态,确保资源的释放。或者将线程置为joinable,而后适时调用pthread_join.
还有2个函数能够实现线程的分离,pthread_detach(threadid)和pthread_detach(pthread_self())。
这2个函数区别是调用他们的线程不一样,没其余区别。
pthread_detach(threadid)函数的功能是使线程ID为threadid的线程处于分离状态,一旦线程处于分离状态,该线程终止时底层资源当即被回收;不然终止子线程的状态会一直保存(占用系统资源)直到主线程调用pthread_join(threadid,NULL)获取线程的退出状态。
一般是主线程使用pthread_create()建立子线程之后,通常能够调用pthread_detach(threadid)分离刚刚建立的子线程,这里的threadid是指子线程的threadid;如此以来,该子线程止时底层资源当即被回收;
被建立的子线程也能够本身分离本身,子线程调用pthread_detach(pthread_self())就是分离本身,由于pthread_self()这个函数返回的就是本身自己的线程ID。
注:在分离属性状况下,一个线程结束时会当即释放它所占有的系统资源,但有一点要注意的是,若是设置一个线程分离属性,而这个线程又运行得很是快的话,那么它极可能在pthread_create函数返回以前就终止了线程函数的运行,它终止之后就颇有可能将线程号和系统资源移交给其余的线程使用,这时调用pthread_create的线程就获得错误的线程号。