• 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. ");

                       sleep(1);

             }

    return (void *)0;

    }

     

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

    {

             inti;

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

                       printf("pthread2. ");

                       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. ");

                       return1;

             }

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

             if(ret)

             {

                       perror("createthread 2 failed. ");

                       return1;

             }

     

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

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

             return0;

    }

     

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

    /*

     *pthread_init.c

     *

     * Created on: Jan 20, 2013

     *     Author: linuxdba@qq.com

     */

     

    #include <stdio.h>

    #include <pthread.h>

     

    void *create(void *arg)

    {

             int *num;

            num = (int*)arg;

             printf("theinput number is: %d. ", *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. ");

                       return1;

             }

             pthread_join(pthid,NULL);

             return0;

    }

     

    示例三:共享数据

    /*

     *pthread_share.c

     *

     * Created on: Jan 20, 2013

     *     Author: linuxdba@qq.com

     */

     

    #include <stdio.h>

    #include <pthread.h>

     

    static int i = 3;

    void *pthread_1(void)

    {

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

             return(void *)0;

    }

     

    void *pthread_2(void)

    {

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

             return(void *)0;

    }

     

    int main(int argc, char argv[])

    {

             intret = 0;

             inti = 5;

             pthread_tpthid1, pthid2;

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

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

             if(ret)

             {

                       printf("createthread 1 failed. ");

                       return1;

             }

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

             if(ret)

             {

                       printf("createthread 2 failed. ");

                       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: linuxdba@qq.com

     */

     

    #include <stdio.h>

    #include <pthread.h>

     

    void *clean1(void *arg)

    {

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

             return(void *)0;

    }

     

    void *clean2(void *arg)

    {

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

             return(void *)0;

    }

     

    void *thread(void )

    {

             pthread_tthid;

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

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

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

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

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

             printf("Inthread. ");

             pthread_exit("threadexit. ");       //退出线程,会执行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. ");

                       return-1;

             }

             printf("theprocess is: %d. ", 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

  • 相关阅读:
    JSP
    Map集合的四种遍历
    过滤器和监听器
    Web常用对象(2)
    Web常用对象(1)
    Java Web了解和Servlet初次见面
    面向对象之继承(1)
    SpringBoot使用简单缓存
    SpringBoot整合mybatis
    Spring Security 入门学习--数据库认证和授权
  • 原文地址:https://www.cnblogs.com/sunminmin/p/4484865.html
Copyright © 2020-2023  润新知