linux多线程API

1. pthread_t:线程ID

    实际上是一个unsinged long int 类型,用来表示线程id

2. pthread_attr_t:线程属性

    包括scope属性、detach属性、堆栈地址、堆栈大小、优先级。在pthread_create中,把第二个参数设置为NULL的话,将采用默认的属性配置。

3. pthread_create():创建一个线程

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

        tidp:指向线程标识符的指针

        attr:用来设置线程属性

        start_rtn:线程运行起始地址,也就是传递一个参数的地址,注意这个参数实际上是一个函数指针

        arg:传递给线程的参数

4. pthread_exit():终止当前线程

        在不终止整个进程的前提下,一个线程终止有如下三种方式:

         a.线程从例程中返回

          b.线程可以自己调用pthread_exit()终止自身

          c.其他线程可以调用pthread_cancel()终止其它进程,调用pthread_cancel后,被要求取消的线程不会立刻停止,会一直运行到取消点,然后检测是否需要停止。


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

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

    int pthread_join(pthread_t id,void **retval);

    返回值:0是成功,非0失败

    id:等待的线程id

    retval:用户定义的指针,用来存储被等待线程的返回值

7. pthread_attr_init():初始化线程的属性
8. pthread_attr_setdetachstate():设置脱离状态的属性(决定这个线程在终止时是否可以被结合)
9. pthread_attr_getdetachstate():获取脱离状态的属性
10. pthread_attr_destroy():删除线程的属性

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

-------------------------------------------------------互斥锁------------------------------------------------------------------

1. pthread_mutex_t 

    锁的创建方式有两种,静态和动态

    静态初始化锁:

        pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER

    动态创建锁:

        int pthread_mutex_init(pthread_mutex_t* mutex,const pthread_mutexattr_t *attr)

        成功则返回0,返回其他任何值都是失败...需要注意貌似多线程这块的返回值都是0代表成功

    

2.  pthread_mutex_init() 初始化互斥锁

3. pthread_mutex_destroy()

    释放锁占用的资源,前提是锁必须是未被锁状态,成功返回0,其余返回代表错误

4. pthread_mutex_lock():占有互斥锁(阻塞操作)

    如果锁可用,则锁定这个锁,然后返回0,如果锁不可用,则阻塞等待,直到锁可用,然后锁定,返回0,返回其他代表失败

5. pthread_mutex_trylock()

    如果锁可用,则锁定这个锁,然后返回0,如果锁不可用,则立刻返回一个EBUSY状态,和4的区别就是这个函数不阻塞

6. pthread_mutex_unlock()

    成功返回0,失败返回其它

------------------------------------------------------条件变量---------------------------------------------------------------

1. 条件变量

    pthread_cond_t 

    条件变量,和互斥锁一样,有静态和动态两种初始化方法

    静态:pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

    动态:调用pthread_cond_init()方法

2. 动态初始化条件变量

    int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t * attr)

    初始化一个条件变量,成功返回0,失败返回其他

3. 销毁条件变量

    int pthread_cond_destroy(pthread_cond_t *cond)

    成功返回0,失败返回其他

4. 等待条件变量的特殊条件发生

    int pthread_cond_wait(pthread_cond_t * cond,pthread_mutex_t* mutex)

    等待条件得到满足才会继续执行

    int pthread_cond_wait(pthread_cond_t * cond,pthread_mutex_t* mutex,struct timespec *abstime)

    在等待abstime时间内,如果条件满足则继续执行,如果等待到了abstime时间,则返回TIMEOUT,同时结束等待

    linux多线程API

    刚开始一直迷惑,为什么条件变量要配合一个mutex来操作,其逻辑是用mutex来确保这个线程在进入等待和出等待这两个过程中不受到任何干扰。这里的干扰有两方面

    1.来自别的线程的signal。A线程正在进入等待,这个时候B线程发过一个sinal...这会导致A在进入等待的过程中收到了singal,A表示办法处理。

    2. 禁止别的线程修改waitlist。A在进入等待这个过程中,要修改waitlist,可以把waitlist理解成临界资源,不能同时被多个线程修改。所以要用到互斥锁

这个图的流程如下:

    a.   线程1想要进入等待,这个时候它先拿锁,然后走“等待流程”,最后释放锁。

            因为每个线程要走“等待流程”必须拿到锁,所以这样就保证了同一个时间只有一个线程会走“等待流程”。之所以要保证同时只有一个线程走等待流程,是因为这个流程要对某临界资源操作(waitlist);还有一个原因是为了防止在走“等待流程”的过程中收到其它线程发来的singal。

    b.  线程1释放锁以后进就如block的状态。

    c. 在block情况下,线程2要释放信号,于是线程2先拿锁,在释放信号,最后释放锁.

    d.线程1收到了信号,想要做些处理,于是先拿锁,然后去处理,最后再次释放锁

    在c和d这个过程中,可能存在线程2释放了信号,还没来得急释放锁,线程1就收到了信号的情况,这种情况下线程1因为拿不到锁,所以还要继续等待....

5. 唤醒进入等待状态的线程

    int pthread_cond_signal(pthread_cond_t *cond);

    唤醒被阻塞在指定条件变量的其他线程,成功返回0,失败返回其他