第11章 线程

  1. 线程标识
    就像每个进程有一个进程ID一样,每个线程也有一个线程ID。进程ID在整个系统中是唯一的,但线程ID不同,线程ID只有在它所属的进程上下文中才有意义。
    进程ID 用pid_t数据类型表示
    线程ID用pthread_t数据类型来表示
    #include<pthread.h>
    int pthread_equal(pthread_t tid1,pthread_t tid2)
    返回值:若相等,返回非0数值;否则,返回0
    线程可以通过调用pthread_self函数获得自身的线程ID
    #include<pthread.h>
    pthread_t pthread_self(void);
    返回值:调用线程的线程ID
    这样可以指定特定的线程完成特定的事情
  2. 线程创建
    新增的线程可以通过调用pthread_create函数创建
    #include<pthread.h>
    int pthread_create(pthread_t * restrict tidp, const pthread_attr_t *restrict attr, void *(*start_trn)(void *), void *restrict arg);
    返回值: 若成功,返回0, 否则 返回错误编码
    当pthread_create成功返回时,新创建线程的线程ID会被设置成tidp指向的内存单元。
    attr参数用于定制各种不同的线程属性。(设置为null 创建一个具有默认属性的线程)
    新创建的线程从start_trn函数的地址开始运行,该函数只有一个无类型指针参数arg。如果需要向start_trn函数传递的参数有一个以上,那么需要把这些参数放到一个结构体重,然后把这个结构的地址作为arg参数传入。
    线程创建时并不能保证哪个线程会先运行:是新创建的线程,还是调用线程。
    新创建的线程可以访问进程的地址空间,并且继承调用线程的浮点环境和信号屏蔽字,但是该线程的挂起信号集会被清除
    #include "apue.h"
    #include "pthread.h"
    
    void printids(const char *s)
    {
        pid_t     pid;
        pthread_t tid;
    
        pid = getpid();
        tid = pthread_self();
        printf("%s pid %lu tid %lu (0x%lx)\n",s,(unsigned long)pid,(unsigned long)tid, (unsigned long)tid);
    }
    voud *thr_fn(void *arg)
    {
        printftids("new thread:");
        return ((void*)0);
    }
    int main(void)
    {
        int err;
        err = pthread_create(&ntid,NULL,thr_fn,NULL);
        if(err!=0)
            err_exit(err,"can;t create thread");
        printids("main thread:");
        Sleep(1);
        exit(0);
    }
    本实例有两个特别之处,需要处理主线程和新线程之间的竞争。第一个特别:主线程需要休眠,如果主线程不休眠,它就可能退出,这样新线程还没有机会运行,整个进程就已经终止了。第二个特别在于新线程通过pthread_self函数获取自己的线程ID,而不是从共享内存读取。
    结果:
    main thread: pid 20075 tid 1 (0x1)
    new thread:pid 20075 tid 2 (0x2)
  3. 线程终止
    单个线程可以通过3种方式退出
    1)线程可以简单地从启动例程中返回,返回值是线程的退出码
    2)线程可以被同一进程中的其它线程取消
    3)线程调用pthread_exit
    #include<pthread.h>
    void pthread_exit(void *rval_ptr)
    rval_ptr参数是一个无类型指针。
    #include<pthread.h>
    void pthread_join(pthread_t thread,void **rval_ptr)
    调用线程将一直阻塞,直到制定的线程调用票pthread_exit,从启动例程中返回或者被取消
    线程可以调用pthread_cancel函数来请求取消同一进程中的其它线程
    #include<pthread.h>
    int pthread_cancel(pthread_t tid);
    返回值:若成功 返回0 否则 返回错误编号
    一个线程可以建立多个清理处理程序。处理程序记录在栈中,也就是说,它们的执行顺序与它们注册时相反。
    #include<pthread.h>
    int pthread_cleanup_push(void (*trn)(void *),void *arg);
    void pthread_cleanup_pop(int execute)
    
  4. 线程同步
    互斥量 mutex  互斥变量是用pthread_mutex_t 数据类型表示的。使用前必须对其初始化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值