打印

linux多线程常用相关函数简介

[复制链接]
193|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
过期账户|  楼主 | 2018-9-20 19:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
由于pthread库不是Linux系统默认的库,连接时需要使用库实打实的libpthread.a,需在编译时加-lpthread参数



pthread_create

原型:int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,(void*)(*start_rtn)(void*),void *arg)

用法:#include

功能:pthread_create是类Unix操作系统(Unix、Linux、Mac OS X等)的创建线程的函数

说明:函数若线程创建成功,则返回0,若线程创建失败,则返回出错编号。返回成功时,由tidp指向的内存单元被设置为新创建线程的线程ID,attr参数用于指定各种不同的线程属性,新创建的线程从start_rtn函数的地址开始运行,该函数只有一个万能指针参数arg,如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。

pthread_create()中的attr参数是一个结构指针,结构中的元素分别对应着新线程的运行属性,主要包括以下几项:

__detachstate,表示新线程是否与进程中其他线程脱离同步,如果置位则新线程不能用pthread_join()来同步,且在退出时自行释放所占用的资源。缺省为PTHREAD_CREATE_JOINABLE状态。这个属性也可以在线程创建并运行以后用pthread_detach()来设置,而一旦设置为PTHREAD_CREATE_DETACH状态(不论是创建时设置还是运行时设置)则不能再恢复到 PTHREAD_CREATE_JOINABLE状态。

__schedpolicy,表示新线程的调度策略,主要包括SCHED_OTHER(正常、非实时)、SCHED_RR(实时、轮转法)和 SCHED_FIFO(实时、先入先出)三种,缺省为SCHED_OTHER,后两种调度策略仅对超级用户有效。运行时可以用过 pthread_setschedparam()来改变。

__schedparam,一个struct sched_param结构,目前仅有一个sched_priority整型变量表示线程的运行优先级。这个参数仅当调度策略为实时(即SCHED_RR 或SCHED_FIFO)时才有效,并可以在运行时通过pthread_setschedparam()函数来改变,缺省为0。

__inheritsched,有两种值可供选择:PTHREAD_EXPLICIT_SCHED和PTHREAD_INHERIT_SCHED,前者表示新线程使用显式指定调度策略和调度参数(即attr中的值),而后者表示继承调用者线程的值。缺省为PTHREAD_EXPLICIT_SCHED。__scope,表示线程间竞争CPU的范围,也就是说线程优先级的有效范围。POSIX的标准中定义了两个值: PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示与系统中所有线程一起竞争CPU时间,后者表示仅与同进程中的线程竞争CPU。目前LinuxThreads仅实现了PTHREAD_SCOPE_SYSTEM一值。

pthread_attr_t结构中还有一些值,但不使用pthread_create()来设置。为了设置这些属性,POSIX定义了一系列属性设置函数,包括pthread_attr_init()、pthread_attr_destroy()和与各个属性相关的pthread_attr_get---/pthread_attr_set---函数。

范例:



点击(此处)折叠或打开



    #include <stdio.h>

    #include <stdlib.h>

    #include <pthread.h>

    #include <unistd.h>

     

    #define NUM_THREADS 8

     

    void *PrintHello(void *args)

    {

        int thread_arg;

        sleep(1);

        thread_arg = (int)args;

        printf("Hello from thread %d\n", thread_arg);

        return NULL;

    }

     

    int main(void)

    {

        int rc,t;

        pthread_t thread[NUM_THREADS];

     

        for( t = 0; t < NUM_THREADS; t++)

        {

            printf("Creating thread %d\n", t);

            rc = pthread_create(&thread[t], NULL, PrintHello, (void *)t);

            if (rc)

            {

                printf("ERROR; return code is %d\n", rc);

                return EXIT_FAILURE;

            }

        }

        for( t = 0; t < NUM_THREADS; t++)

            pthread_join(thread[t], NULL);

        return EXIT_SUCCESS;

    }





pthread_join

原型: int pthread_join(pthread_t thread, void **retval)

用法:#include

功能:pthread_join()函数,以阻塞的方式等待thread指定的线程结束

说明:当函数返回时,被等待线程的资源被收回。如果进程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。参数含义如下:thread: 线程标识符,即线程ID,标识唯一线程,retval: 用户定义的指针,用来存储被等待线程的返回值,成功时返回0, 失败时返回的则是错误号。

代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。

范例:

 // 子线程阻塞,等待信号,然后输出字符串

  // 主线程从键盘录入字符,给子线程发信号。



点击(此处)折叠或打开



    #include<stdio.h>

    #include<unistd.h>

    #include<signal.h>

    #include<pthread.h>

    #include<time.h>

    pthread_t tid; 

    sigset_t set;

    void myfunc()

    {

         printf("hello\n");

    }

    static void* mythread(void*p)

    {

         int signum;

         while(1){

             sigwait(&set,&signum);

             if(SIGUSR1==signum)

                 myfunc();

             if(SIGUSR2==signum)

                 {

                 printf("Iwillsleep2secondandexit\n");

                 sleep(2);

                 break;

                 }

        }

    }

    int main()

    {

        char tmp;

        void*status;

        sigemptyset(&set);

        sigaddset(&set,SIGUSR1);

        sigaddset(&set,SIGUSR2);

        sigprocmask(SIG_SETMASK,&set,NULL);

        pthread_create(&tid,NULL,mythread,NULL);

        while(1)

        {

            printf(":");

            scanf("%c",&tmp);

            if('a'==tmp)

            {

                pthread_kill(tid,SIGUSR1);//发送SIGUSR1,打印字符串。

            }

            elseif('q'==tmp)

            {

                //发出SIGUSR2信号,让线程退出,如果发送SIGKILL,线程将直接退出。

                pthread_kill(tid,SIGUSR2);

                //等待线程tid执行完毕,这里阻塞。

                pthread_join(tid,&status);

                printf("finish\n");

                break;

            }

            else

                continue;

        }

        return 0;

    }





pthread_self

原型:pthread_t pthread_self(void)

用法:#include

功能:获取当前调用线程的 thread identifier(标识号)

说明:pthread_t的类型为unsigned long int,所以在打印的时候要使用%lu方式,否则将产生神奇的结果。

范例:



点击(此处)折叠或打开



    #include <pthread.h>

    #include <stdio.h>

    int main()

    {

        pid_t pid;

        pthread_t tid;

        pid = getpid();

        tid = pthread_self();

        /* tid是unsigned long int,这里只是方便转换 */

        printf("pid %u tid %u (0x%x)\n", (unsigned int)pid,(unsigned int)tid, (unsigned int)tid);

        return 0;

    }





pthread_exit

原型:void  pthread_exit(void  *retval)

用法:#include

功能:使用函数pthread_exit退出线程,这是线程的主动行为;由于一个进程中的多个线程是共享数据段的,因此通常在线程退出之后,退出线程所占用的资源并不会随着线程的终止而得到释放,但是可以用pthread_join()函数来同步并释放资源。

说明:retval:pthread_exit()调用线程的返回值,可由其他函数如pthread_join来检索获取。

范例:



点击(此处)折叠或打开



    #include <stdio.h>

    #include <pthread.h>



    /*thread 1*/

    void thread_1(void)

    {

        int i=0;

        for(i=0;i<=6;i++)

        {

            printf("This is a pthread_1.\n");

            if(i==2)

                pthread_exit(0); //用pthread_exit()来调用线程的返回值,用来退出线程,但是退出线程所占用的资源不会随着线程的终止而得到释放

            sleep(1);

        }

    }



    /*thread 2*/

    void thread_2(void)

    {

        int i;

        for(i=0;i<3;i++)

            printf("This is a pthread_2.\n");

        pthread_exit(0);//用pthread_exit()来调用线程的返回值,用来退出线程,但是退出线程所占用的资源不会随着线程的终止而得到释放

    }



    int main(void)

    {

        pthread_t id_1,id_2;

        int i,ret;

        /*创建thread 1*/

        ret=pthread_create(&id_1,NULL,(void *) thread_1,NULL);

        if(ret!=0)

        {

            printf("Create pthread error!\n");

            return -1;

        }

        /*创建thread 2*/

        ret=pthread_create(&id_2,NULL,(void *) thread_2,NULL);

        if(ret!=0)

        {

            printf("Create pthread error!\n");

            return -1;

        }

        /*等待线程结束*/

        pthread_join(id_1,NULL);

        pthread_join(id_2,NULL);

        return 0;

    }

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

395

主题

395

帖子

0

粉丝