不同的进程需要不同的资源,进程间通信较复杂,耗用资源较多。 相对于进程而言,线程的建立更快,且不需要额外的资源,同一进程下的不同线程共同使用该进程所拥有的资源(如数据空间)。线程间通信很容易。一个复杂的进程可以分为多个独立的或者半独立的进程。
在进程中,线程被创建过后,处于就绪态。创建该线程的进程继续处于执行态。当该进程退出执行态后(比如遇到sleep(n)语句),线程才可以被执行(进入执行态)。若创建线程的进程结束了(如return),则被创建的线程也被强行结束(即使该线程还未执行)。
在创建线程后,要注意用pthread_cleanup_push("清理函数")及pthread_cleanup_pop(A)函数对线程所用资源进行释放。从pthread_cleanup_push()的调用点到pthread_cleanup_pop()调用点之间的程序段在执行时发生的终止动作(包括调用pthread_exit()终止和异常终止,但不包括return终止)都将引发pthread_cleanup_push()所指定的清理函数的执行。若pthread_cleanup_push()调用点与pthread_cleanup_pop()调用点之间的代码执行时没有发生终止动作,则程序执行到pthread_cleanup_pop(A)时,如果A为非零则执行指定的清理函数,若为零,则不执行清理函数。
例1.1:有如下线程
//清理函数
void *clean(void *arg)
{
printf("cleanup :%s \n",(char *)arg);
return (void *)0;
}
//线程
void *thr_fn1(void *arg)
{
printf("thread 1 start \n");
pthread_cleanup_push( (void*)clean,"thread 1 first handler");
printf("thread 1 push complete \n");
if(1)
{
pthread_exit((void *)2);
}
pthread_cleanup_pop(0);
return (void *)1;
}
其中,pthread_cleanup_push()调用点与pthread_cleanup_pop()调用点之间的代码执行时会发生pthread_exit终止,所以将执行清理函数。运行结果如下:
thread 1 start
thread 1 push complete
thread 1 first handler
例1.2:有如下线程
//清理函数
void *clean(void *arg)
{
printf("cleanup :%s \n",(char *)arg);
return (void *)0;
}
//线程
void *thr_fn1(void *arg)
{
printf("thread 1 start \n");
pthread_cleanup_push( (void*)clean,"thread 1 first handler");
printf("thread 1 push complete \n");
if(1)
{
return((void *)1);
}
pthread_cleanup_pop(0);
return (void *)1;
}
thread 1 start
thread 1 push complete
例2.1:有如下线程
//清理函数
void *clean(void *arg)
{
printf("cleanup :%s \n",(char *)arg);
return (void *)0;
}
//线程
void *thr_fn1(void *arg)
{
printf("thread 1 start \n");
pthread_cleanup_push( (void*)clean,"thread 1 first handler");
printf("thread 1 push complete \n");
pthread_cleanup_pop(0);
return (void *)1;
}
其中,pthread_cleanup_push()调用点与pthread_cleanup_pop()调用点之间的代码执行时没有发生终止动作,且程序执行到pthread_cleanup_pop(0)函数时,由于其参数值为“0”,所以不会执行清理函数。输出如下:
thread 1 start
thread 1 push complete
例2.2:有如下线程
//清理函数
void *clean(void *arg)
{
printf("cleanup :%s \n",(char *)arg);
return (void *)0;
}
//线程
void *thr_fn1(void *arg)
{
printf("thread 1 start \n");
pthread_cleanup_push( (void*)clean,"thread 1 first handler");
printf("thread 1 push complete \n");
pthread_cleanup_pop(1);
return (void *)1;
}
其中,pthread_cleanup_push()调用点与pthread_cleanup_pop()调用点之间的代码执行时没有发生终止动作,但程序执行到pthread_cleanup_pop(0)函数时,由于其参数值为“1”,所以会执行清理函数。输出如下:
thread 1 start
thread 1 push complete
例3:有如下线程
//清理函数
void *clean(void *arg)
{
printf("cleanup :%s \n",(char *)arg);
return (void *)0;
}
//线程
void *thr_fn1(void *arg)
{
printf("thread 1 start \n");
pthread_cleanup_push( (void*)clean,"thread 1 first handler");
pthread_cleanup_push( (void*)clean,"thread 1second handler");
printf("thread 1 push complete \n");
if(1)
{
pthread_exit((void *)2);
}
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
return (void *)1;
}
其中,pthread_cleanup_push()调用点与pthread_cleanup_pop()调用点之间的代码执行时会发生pthread_exit终止,所以将执行清理函数。且pthread_cleanup_push与pthread_cleanup_pop是压栈和弹栈过程,应遵循先进后出的规则。运行结果如下:
thread 1 start
thread 1 push complete
thread 1 second handler
thread 1 first handler