避免死锁:
1,固定加锁层次
如果需要同时加锁A,B,那么固定加锁顺序,比如只能先加锁A,后加锁B;
2,试加锁和回退
如果加锁集合中第一个互斥量,那么对其他互斥量加锁时,使用pthread_mutex_trylock如果失败,释放所有已经加的锁
链锁:
两个锁的范围叠加,当代码锁住一个互斥量进入区域时,还需要第二个互斥量;
链锁应该用在多个线程同时活跃在层次的不同部分时
TYPE
pthread_t 线程标识符
pthread_mutex_t 互斥量
pthraed_code_t 条件变量
pthread_ket_t 线程私有权握访问键
pthread_attr_t 线程属性对象
pthread_mutexattr_t 互斥量属性对象
pthread_condattr_t 条件变量属性对象
pthread_once_t 一次性初始化 控制变量API
int pthread_equal(pthread_t t1, pthread_t t2);
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void* (*start) (void*), void *arg)
pthread_t pthread_self(void);
int sched_yield(void);
int pthread_exit(void*value_ptr);//终止线程的执行,如果main线程调用,那么子线程会执行完,但是如果main线程调用return,子线程会直接结束,参数为返回的字符串
int pthread_detach(pthread_t thread); //分离一个正在运行的线程不对线程带来任何影响,仅仅是通知系统当该线程结束时,其所属资源会被回收.
一个没被分离的线程终止时,会保留虚拟内存,包括他们的堆栈,还有其他系统资源.线程自身detach之后,其他线程在使用pthread_join就会报错,因为线程资源以及释放
int pthread_join(pthread_t thread, void **val); //等待线程结束,释放thread线程资源
pthread_join 和pthread_detach 看谁先后执行,决定pthread_join释放能获取到状态,
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER 静态初始化默认属性的互斥量
int pthread_mutex_init(pthread_mutex_t *mutex,pthread_mutex_attr_t *attr);动态初始化互斥量
int pthread_mutex_destory(pthread_mutex_t *mutex); 在释放动态初始化的互斥量之后,在释放空间,也就destory,然后free
文件=锁
flockfile()
ftrylockfile()
funlockfile()
获取用户和终端ID
getlogin_r
ctermid()
ttyname_r()
搜获目录
readdir_r
字符串
strtok_r
时间表示
char *asctime_r(), ctime_r () , gmtime_r(), localtime_t(),read_r
组数据库:getgrgid_r, getgrnam_r,
用户数据库:getpwuid_r,getpwnam_r
获取系统变量的值sysconf
信号
当线程和信号相遇时,只要有可能尽量在主线程使用pthread_sigmask来屏蔽信号,然后同步的在专用线程
中使用sigwait,如果必须在线程内使用sigaction(或等价)的处理同步信号(如SIGSEGV),要特别小心,
信号处理函数内应尽量少做工作
与硬件相关的同步信号包括SIGSEGV,SIGFPE,SIGTRAP,他们被送到引起该硬件情况的线程,肯定不会送到其他线程
线程信号掩码函数 :pthread_sigmask(),一个线程创建时,他继承了创建该线程的信号掩码。
pthread_kill()向指定的线程发送信号,仅限本进程内,如果发送SIGKILL信号,信号不止会杀死指定线程,还会杀死所有线程(包括主线程)
SIGSTOP和SIGKILL信号是不可捕获的
SIGTSTP与SIGSTOP都是使进程暂停(都使用SIGCONT让进程重新激活)。唯一的区别是SIGSTOP不可以捕获。
捕捉SIGTSTP后一般处理如下:
1)处理完额外的事
2)恢复默认处理
3)发送SIGTSTP信号给自己。(使进程进入suspend状态。)
int raise(int sig); 给当前线程或进程发信号
对信号集的处理
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);