Linux之多线程20160705

简单介绍一下多线程的API,线程的概念类似与一个任务或者说一个函数,线程一旦被创建就会运行,具体使用方法可以在Linux下使用man 命令查看:

pthread_t:线程ID

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():向线程发送一个信号
pthread_mutex_init() 初始化互斥锁

pthread_mutex_destroy() 删除互斥锁

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

pthread_mutex_trylock():试图占有互斥锁(不阻塞操作)。即,当互斥锁空闲时,将占有该锁;否则,立即返回。

pthread_mutex_unlock(): 释放互斥锁

pthread_cond_init():初始化条件变量

pthread_cond_destroy():销毁条件变量

pthread_cond_signal(): 唤醒第一个调用pthread_cond_wait()而进入睡眠的线程

pthread_cond_wait(): 等待条件变量的特殊条件发生

Thread-local storage(或者以Pthreads术语,称作线程特有数据):

pthread_key_create(): 分配用于标识进程中线程特定数据的键

pthread_setspecific(): 为指定线程特定数据键设置线程特定绑定

pthread_getspecific(): 获取调用线程的键绑定,并将该绑定存储在 value 指向的位置中

pthread_key_delete(): 销毁现有线程特定数据键

pthread_attr_getschedparam();获取线程优先级

pthread_attr_setschedparam();设置线程优先级
pthread_equal(): 对两个线程的线程标识号进行比较

pthread_detach(): 分离线程


创建一个线程默认的状态是joinable, 如果一个线程结束运行但没有被join,则它的状态类似于进程中的Zombie
Process,即还有一部分资源没有被回收(退出状态码),所以创建线程者应该pthread_join来等待线程运行结束,并
可得到线程的退出代码,回收其资源(类似于wait,waitpid)
但是调用pthread_join(pthread_id)后,如果该线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如
此,比如在Web服务器中当主线程为每个新来的链接创建一个子线程进行处理的时候,主线程并不希望因为调用
pthread_join而阻塞(因为还要继续处理之后到来的链接),这时可以在子线程中加入代码
pthread_detach(pthread_self())
或者父线程调用
pthread_detach(thread_id)(非阻塞,可立即返回)
这将该子线程的状态设置为detached,则该线程运行结束后会自动释放所有资源
pthread_self(): 查询线程自身线程标识号
pthread_detach(pthread_self())
linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,
如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(
总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。
若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。

unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:
pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为 joinable,然后
适时调用pthread_join.

其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接
pthread_exit线程就会自动退出。省去了给线程擦屁股的麻烦

eg:

pthread_t tid;
int status = pthread_create(&tid, NULL, ThreadFunc, NULL);
if(status != 0)
{
perror("pthread_create error");
}
pthread_detach(tid);

pthread_self(): 查询线程自身线程标识号

pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);设置当前的线程的大小
linux查看修改线程默认栈空间大小 ulimit -s

1、通过命令 ulimit -s 查看linux的默认栈空间大小,默认情况下 为10240 即10M

2、通过命令 ulimit -s 设置大小值 临时改变栈空间大小:ulimit -s 102400, 即修改为100M

3、可以在/etc/rc.local 内 加入 ulimit -s 102400 则可以开机就设置栈空间大小

4、在/etc/security/limits.conf 中也可以改变栈空间大小:

#<domain> <type> <item> <value>

* soft stack 102400

重新登录,执行ulimit -s 即可看到改为102400 即100M


/******************************************************************************************************************/

. 初始化和销毁:

#include <pthread.h>

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

读和写:

#include <pthread.h>

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

成功则返回0, 出错则返回错误编号.

这3个函数分别实现获取读锁, 获取写锁和释放锁的操作. 获取锁的两个函数是阻塞操作, 同样, 非阻塞的函数为:

#include <pthread.h>

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

成功则返回0, 出错则返回错误编号.

非阻塞的获取锁操作, 如果可以获取则返回0, 否则返回错误的EBUSY

posted @ 2016-07-05 17:53  yuweifeng  阅读(838)  评论(0编辑  收藏  举报