POSIX多线程之创建线程pthread_create && 线程清理pthread_cleanup

 

多线程之pthread_create创建线程

 

pthreads定义了一套C程序语言类型、函数、与常量。以pthread.h和一个线程库实现。

数据类型:

pthread_t:线程句柄

pthread_attr_t:线程属性

线程操作函数:

pthread_create():创建一个线程

pthread_exit():终止当前线程

pthread_cancel():中断另外一个线程的运行

pthread_join():阻塞当前的线程,直到另外一个线程运行结束

pthread_attr_init():初始化线程的属性

pthread_attr_setdetachstate():设置脱离状态的属性

pthread_attr_getdetachstate():获取脱离状态的属性

pthread_attr_destroy():删除线程的属性

pthread_kill():向线程发送一个信号

.....

 

创建线程:

int pthread_create(pthread_t *thread, const pthread_attr_t  *attr, void *(*start_rtn)  (void*),void  *arg);

 

*thread:线程id (指向线程标识符的指针)

*attr:线程属性(通常为空)

*start_rtn:线程要执行的函数(线程运行函数的起始地址)

*arg:start_rtn的参数

返回值为零才算成功,其它表示错误

编译时需要加上 -lpthread

 

示例一:

#include <stdio.h>

#include <pthread.h>

 

void *pthread_1(void)      //线程1执行的函数

{

         inti;

         for(i=1; i < 5; i++){

                   printf("pthread1.\n");

                   sleep(1);

         }

return (void *)0;

}

 

void *pthread_2(void)      //线程2执行的函数

{

         inti;

         for(i=1;i < 5; i++){

                   printf("pthread2.\n");

                   sleep(1);

         }

return (void *)0;

}

 

int main(int argc, char argv[])

{

         intret = 0;

         pthread_tpthid1, pthid2;        //线程的id

         ret= pthread_create(&pthid1,NULL, (void *)pthread_1, NULL);

         if(ret)       // 0则创建失败

         {

                   perror("createthread 1 failed.\n");

                   return1;

         }

         ret= pthread_create(&pthid2, NULL, (void *)pthread_2, NULL);

         if(ret)

         {

                   perror("createthread 2 failed.\n");

                   return1;

         }

 

         pthread_join(pthid1,NULL);    //等待pthid1,否则不会等待,继续往下执行

         pthread_join(pthid2,NULL);    //如无,遇到下面的return会结束进程

         return0;

}

 

示例二:传递参数,初始化

/*

 *pthread_init.c

 *

 * Created on: Jan 20, 2013

 *     Author: [email protected]

 */

 

#include <stdio.h>

#include <pthread.h>

 

void *create(void *arg)

{

         int *num;

        num = (int*)arg;

         printf("theinput number is: %d.\n", *num);

         return(void *)0;

}

 

 

int main(int argc, char argv[])

{

         intret;

         intt;

         printf("Inputone number:");

         scanf("%d",&t);

 

         int*attr = &t;

         pthread_tpthid;

         ret= pthread_create(&pthid, NULL, (void *)create, (void *)attr);

         if(ret)

         {

                   perror("createthread failed.\n");

                   return1;

         }

         pthread_join(pthid,NULL);

         return0;

}

 

示例三:共享数据

/*

 *pthread_share.c

 *

 * Created on: Jan 20, 2013

 *     Author: [email protected]

 */

 

#include <stdio.h>

#include <pthread.h>

 

static int i = 3;

void *pthread_1(void)

{

         printf("thread1, i is: %d.\n", i);

         return(void *)0;

}

 

void *pthread_2(void)

{

         printf("thread2, i is: %d.\n", i);

         return(void *)0;

}

 

int main(int argc, char argv[])

{

         intret = 0;

         inti = 5;

         pthread_tpthid1, pthid2;

         printf("mainthread, i is: %d.\n", i);

         ret= pthread_create(&pthid1, NULL, (void *)pthread_1, NULL);

         if(ret)

         {

                   printf("createthread 1 failed.\n");

                   return1;

         }

         ret= pthread_create(&pthid2, NULL, (void *)pthread_2, NULL);

         if(ret)

         {

                   printf("createthread 2 failed.\n");

                   return1;

         }

         pthread_join(pthid1,NULL);

         pthread_join(pthid2,NULL);

         return0;

}

此段程序之中两个线程是对等的,不存在先后顺序;

i 为全局变量,main函数内部为局部的变量。

 

http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_create.3.html

http://baike.baidu.com/view/974776.htm

 

多线程设计之线程清理pthread_cleanup

 

 

线程清理:pthread_cleanup_push() &  pthread_cleanup_pop()

 

A cancellation clean-up handler is poppedfrom the stack and executed in

The following circumstances:(三种情况会执行线程清理)

1.        When a thread is canceled, allof the stacked clean-up handlers are popped and executed in the reverse of theorder in which they were pushed onto the stack. (线程取消)

2.        When a thread terminates bycallingpthread_exit(3),all clean-up handlers are executed as described in the preceding point.  (Clean-up handlers are not called if thethread terminates by performing a return from the thread start function.) (pushpop之间执行了pthread_exit)

3.        When a thread calls pthread_cleanup_pop()with a nonzero execute argument, the top-most clean-up handler is popped andexecuted.(pop内为非零参数)

 

示例代码:

/*

 *pthread_push_pop.c

 *

 * Created on: Jan 21, 2013

 *     Author: [email protected]

 */

 

#include <stdio.h>

#include <pthread.h>

 

void *clean1(void *arg)

{

         printf("clean1func: %s\n", arg);

         return(void *)0;

}

 

void *clean2(void *arg)

{

         printf("clean2func: %s\n", arg);

         return(void *)0;

}

 

void *thread(void )

{

         pthread_tthid;

         thid= pthread_self();                //获取线程ID

         printf("thethread is: %d.\n",thid);

         printf("theprocess id is: %d.\n", getpid());     //进程ID

         pthread_cleanup_push((void*)clean1,"first push");

         pthread_cleanup_push((void*)clean2, "second push");

         printf("Inthread.\n");

         pthread_exit("threadexit.\n");       //退出线程,会执行push指定函数

         /*return  NULL; */       //不会执行push指定函数

         pthread_cleanup_pop(0);//0,只有在异常退出时才会执行push指定的函数,pop第一个

         pthread_cleanup_pop(1);//为非0,即便是正常,也会执行push指定的函数,pop第二个

         returnNULL;

}

 

int main(int argc, char argv[])

{

         intret = 0;

         pthread_tpthid;

         ret= pthread_create(&pthid, NULL,(void *)thread,NULL);

         if(ret)

         {

                   printf("createthread failed.\n");

                   return-1;

         }

         printf("theprocess is: %d.\n", getpid());         //获取进程ID

         pthread_join(pthid,NULL);

 

}

 

运行结果:

the process is: 3893.

the thread is:1738999552.

the process id is: 3893.

In thread.

clean2 func: second push

clean1 func: first push

 

push与pop采用栈方式,先进后出,后进先出,所以clean2会在前面。

 

需要注意的几点:

1)        线程属于进程的,只有一个进程ID,一样的;

2)        pushpop是采用栈方式;

3)        pthread_cleanup_pop后面为0则执行push指定函数,非0则即便正常也执行

4)        pushpop之间代码若异常退出,包括pthread_exit,会进行相应的函数处理,但是若其间执行了return,则直接结束线程,不执行push指定函数。

 

参考文档:

http://man7.org/linux/man-pages/man3/pthread_cleanup_push.3.html

 

 

你可能感兴趣的:(pthread)