zoukankan      html  css  js  c++  java
  • APUE学习笔记——11 线程基础

    线程标识

    线程由线程号进行标识。线程号仅在线程所属的进程环境中有效。也就是说属于不同进程的两个线程可能线程号一样。
    线程标识用结构体pthread_t tid表示。与线程Id相关的函数如下:
    比较两个线程ID:
    #include <pthread.h>
    int pthread_equal(pthread_t tid1,pthread_t tid2);
                                  Returns: nonzero if equal, 0 otherwise


    获取自身线程ID:
    #include <pthread.h>
    pthread_t pthread_self(void);
                             Returns: the thread ID of the calling thread

    创建和终止进程:

    创建线程:

    #include <pthread.h>
    int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr,
                        void *(*start_rtn)(void *), void *restrict arg);
                                    Returns: 0 if OK, error number on failure
    


    tidp: 线程ID
    attr:定制线程属性
    start_rtn:新线程从start_rtn指向的函数开始执行
    arg:传入start_rtn指向函数的参数

    线程终止:

    线程有三种终止方式:
    1)从启动例程返回(return),返回值为线程退出码
    2)被同进程的其他线程取消
    3)调用pthread_exit
    1)调用pthread_exit
    #include <pthread.h>
    void pthread_exit(void *rval_ptr);

    启动例程调用pthread_exit 可以退出线程。rval_ptr可以被其他线程通过pthread_join访问到
    #include <pthread.h>
    int pthread_join(pthread_t thread,void **rval_ptr);
                                 Returns: 0 if OK, error number on failure


    pthread_join 使线程发生阻塞,知道thread指向的线程终止,rval_ptr用于获取终止线程的返回值。如果线程是通过被取消的方式结束,则返回值被置为PTHREAD_CANCELED。
    2)被同进程其他线程取消
     
    #include <pthread.h>
    int pthread_cancel(pthread_t tid);
    Returns: 0 if OK, error number on failure

    3)线程的清理

    线程可以构建线程清理程序栈来自定义线程清理程序。(栈:后进先出)
    #include <pthread.h>
    void pthread_cleanup_push(void (*rtn)(void *), void *arg);
    void pthread_cleanup_pop(int execute);

    在三种情况之一,线程清理程序栈被调用
    a.线程调用pthread_exit
    b.应答其他线程的cancellation请求
    c. execute参数非0
    具体使用见后面的example
    #include "apue.h"
    #include "myerr.h"
    #include <pthread.h>
    void
    cleanup(void *arg)
    {
            printf("cleanup: %s
    ", (char *)arg);
    }
    void *
    thr_fn1(void *arg)
    {
            printf("thread 1 start
    ");
            pthread_cleanup_push(cleanup, "thread 1 first handler");
            pthread_cleanup_push(cleanup, "thread 1 second handler");
            printf("thread 1 push complete
    ");
            if (arg)
                    return((void *)1);
            pthread_cleanup_pop(0);
            pthread_cleanup_pop(0);
            return((void *)1);
    }
    void *
    thr_fn2(void *arg)
    {
            printf("thread 2 start
    ");
            pthread_cleanup_push(cleanup, "thread 2 first handler");
            pthread_cleanup_push(cleanup, "thread 2 second handler");
            printf("thread 2 push complete
    ");
            if (arg)
                    pthread_exit((void *)2);
            pthread_cleanup_pop(0);
            pthread_cleanup_pop(0);
            pthread_exit((void *)2);
    }
    int
    main(void)
    {
            int  err;
            pthread_t  tid1, tid2;
            void  *tret;
            err = pthread_create(&tid1, NULL, thr_fn1, (void *)1);
            if (err != 0)
                    err_exit(err, "can’t create thread 1");
            err = pthread_create(&tid2, NULL, thr_fn2, (void *)1);
            if (err != 0)
                    err_exit(err, "can’t create thread 2");
            err = pthread_join(tid1, &tret);
            if (err != 0)
                    err_exit(err, "can’t join with thread 1");
            printf("thread 1 exit code %ld
    ", (long)tret);
            err = pthread_join(tid2, &tret);
            if (err != 0)
                    err_exit(err, "can’t join with thread 2");
            printf("thread 2 exit code %ld
    ", (long)tret);
            exit(0);
    }
               



    执行结果
    windeal@ubuntu:~/Windeal/apue$ ./exe 
    thread 2 start
    thread 2 push complete
    cleanup: thread 2 second handler
    cleanup: thread 2 first handler
    thread 1 start
    thread 1 push complete
    cleanup: thread 1 second handler
    thread 1 exit code 1
    thread 2 exit code 2
    windeal@ubuntu:~/Windeal/apue$ 















  • 相关阅读:
    RegExp实例
    Date类型之组件方法
    Date类型之继承方法
    数组常见方法下
    Math对象
    数组常见方法上
    CSS变量
    基本类型和引用类型
    Python习题集(十五)
    Python习题集(十四)
  • 原文地址:https://www.cnblogs.com/Windeal/p/4284646.html
Copyright © 2011-2022 走看看