创建线程:
# include
int pthread_create(pthread_t *tidp, const pthread_attr_t *attr,
void *(*start_rtn), void *arg)
tidp:创建线程时返回线程id
attr:线程属性(通常为空)
start_rtn:线程要执行的函数
arg:start_rtn的参数
返回值:创建成功就返回0,否则为非0;
编译
因为pthread的库不是linux系统的库,所以在进行编译的时候要加上
-lpthread
# gcc filename -lpthread
下面是一些例子:
1、thread_create.c
# include
# include
void *mythread1(void)
{
int i;
for(i=0; i<3; i++)
{
printf("this is the first pthread.\n");
sleep(1);
}
}
void *mythread2(void)
{
int i;
for(i=0; i<3; i++)
{
printf("this is the second pthread\n");
sleep(1);
}
}
int main(void)
{
int i = 0, ret = 0;
pthread_t id1, id2;
ret = pthread_create(&id1, NULL, (void
*)mythread1, NULL);//创建线程1
if(ret)
{
printf("create pthread error\n");
return 1;
}
ret = pthread_create(&id2, NULL, (void
*)mythread2, NULL);//创建线程2
if(ret)
{
printf("create pthread error\n");
return 1;
}
pthread_join(id1, NULL); //阻塞父进程,直到线程退出程序
pthread_join(id2, NULL);
return 0;
}
运行结果:
[regry@campusnetwork test]$ ./thread_create
this is the first pthread.
this is the second pthread
this is the first pthread.
this is the second pthread
this is the first pthread.
this is the second pthread
2、thread_int.c
# include
# include
# include
void *create(void *arg)
{
int *num;
num = (int *)arg;
printf("create parameter is %d\n", *num);
return (void *)0;
}
int main(int argc, char *argv[])
{
pthread_t tidp;
int error;
int test = 4;
int *attr = &test;
error = pthread_create(&tidp, NULL, (void
*)create, attr);
if(error)
{
printf("pthread_create is created is not created...\n");
return -1;
}
sleep(1);
printf("pthread_create is created...\n");
return 0;
}
运行结果:
[regry@campusnetwork test]$ ./thread_int
create parameter is 4
pthread_create is created...
3、thread_share.c
# include
# include
# include
int a = 1;
void *create(void *arg)
{
printf("new pthread ...\n");
printf("a = %d\n", a);
return (void *)0;
}
int main(int argc, char *argv[])
{
pthread_t tidp;
int error;
int a = 5;
printf("a = %d\n", a);
error = pthread_create(&tidp, NULL, (void
*)create, NULL);//(void *)create 也可以写成create或*create。
if(error != 0)
{
printf("new thread is not create ...\n");
return -1;
}
sleep(1);
printf("new thread is created ...\n");
return 0;
}
程序运行结果:
[regry@campusnetwork test]$ ./thread_share
a = 5
new pthread ...
a = 1
new thread is created ...
终止线程:
如果进程中任何一个线程中调用exit或_exit,那么整个进程都会终止。线程的正常退出方式有:
1、线程从启动例程中返回
2、线程可以被另一个进程终止
3、线程自己调用pthread_exit函数
# include
void pthread_exit(void *rval_ptr)
功能:终止调用线程
Rval_ptr:线程退出返回值的指针。
例子:thread_exit.c
# include
# include
# include
void *create(void *arg)
{
printf("new thread is created ...\n");
return (void *)8;
}
int main(int argc, char *argv[])
{
pthread_t tid;
int error;
void *temp;
error = pthread_create(&tid, NULL, create,
NULL);
printf("main thread !\n");
if(error)
{
printf("thread is not created ...\n");
return -1;
}
error = pthread_join(tid,
&temp);//阻塞父进程,直到指定的线程终止
if(error)
{
printf("thread is not exit ...\n");
return -2;
}
printf("thread is exit code %d \n", (int)temp);
return 0;
}
运行结果:
[regry@campusnetwork test]$ ./thread_exit
main thread !
new thread is created ...
thread is exit code 8
有关pthread_join和pthread_exit的区别可以参看:
线程等待:
# include
int pthread_join(pthread_t tid, void **rval_ptr)
功能:阻塞父进程,直到指定的线程终止。
Tid:等待退出的线程id
Rval_ptr:线程退出的返回值的指针
例子thread_join.c
# include
# include
# include
void *thread(void *str)
{
int i;
for (i = 0; i < 10; i++)
{
sleep(2);
printf("this in the thread:%d\n", i);
}
return NULL;
}
int main(void)
{
pthread_t pth;
int i;
int ret = pthread_create(&pth, NULL, thread, (void
*)(i));
pthread_join(pth, NULL);
printf("123\n");
for(i = 0; i < 10; i++)
{
sleep(1);
printf("this is the main:%d\n", i);
}
return 0;
}
运行结果:
[regry@campusnetwork test]$ ./thread_jon
this in the thread:0
this in the thread:1
this in the thread:2
this in the thread:3
this in the thread:4
this in the thread:5
this in the thread:6
this in the thread:7
this in the thread:8
this in the thread:9
123
this is the main:0
this is the main:1
this is the main:2
this is the main:3
this is the main:4
this is the main:5
this is the main:6
this is the main:7
this is the main:8
this is the main:9
线程标识:
# include
pthread_t pthread_self(void)
功能:
获取调用的线程的thread identifier
实例:thread_id.c
# include
# include
# include
void *create(void)
{
printf("new thread ....\n");
printf("this thread's id is %u\n", (unsigned
int)pthread_self());
printf("the process pid is %d \n", getpid());
return (void *)0;
}
int main(int argc, char *argv[])
{
pthread_t tid;
int error;
printf("main thread is starting ...\n");
error = pthread_create(&tid, NULL, create,
NULL);
if (error)
{
printf("thread is not created ...\n");
return -1;
}
printf("the main process's pid is %d \n", getpid());
sleep(1);
return 0;
}
运行结果:
[regry@campusnetwork test]$ ./thread_id
main thread is starting ...
the main process's pid is 18101
new thread ....
this thread's id is 3086465936
the process pid is 18101
清除:
线程终止有两种情况:正常终止和非正常终止。线程主动调用pthread_exit或者从线程函数中return都将使线程正常退出,这是可以预见的退出方式;非正常终止是线程在其他线程的干预下,或者由于自身运行出错(比如访问非法地址)而退出,这种退出方式是不可以预见的。
不论是可预见的线程终止还是异常终止,都会存在资源释放的问题,如何保证线程终止时能顺利的释放掉自己所占用的资源,是一个必须考虑解决的问题。
从pthread_cleanup_push的调用点到pthread_cleanup_pop之间的程序段中的终止动作(包括调用pthread_exit()和异常终止,不包括return)都将执行pthread_cleanup_push()所指定的清理函数。
# include
void pthread_cleanup_push(void (*rtn)(void *), void *arg)
功能:
将清除函数压入清除栈
Rtn:清除函数
Arg:清除函数的参数
# include
void pthread_cleanup_pop(int execute)
功能:
将清除函数弹出清除栈
参数:execute执行到pthread_cleanup_pop()时是否在弹出清理函数的同时执行该函数,非0:执行;0:不执行
下面是程序一部分:
# include
# include
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 1 second handler");
printf("thread 1 push complete \n");
if (arg)
{
return ((void *)1);
}
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
return (void *)1;
}