Linux编程学习笔记 -- Thread
2013-4-6
线程概念
Linux实现的线程是符合POSIX标准的API。
需要包含的头文件:pthread.h
链接程序时,需要添加 -lpthread
线程的创建
pthread_create() //创建函数,参数:thread function,thread id,传入数据,线程属性
pthread_t // thread ID
pthread_self() //获得线程ID
pthread_equal() //比较线程ID
pthread_join() // 等待线程结束,该函数的第二个参数用来接收线程的返回值,可以返回简单数据类型的值。
线程属性相关类型、操作:
pthread_attr_t
pthread_attr_init()
pthread_attr_destroy()
线程常用属性:detach state
joinable thread 和 detached thread:线程执行完毕后,线程资源是否自动清理。对于joinable thread,调用pthread_join后,线程资源才清理,概念上类似于 zombie 进程。
相关类型、操作:
pthread_attr_setdetachstate() // PTHREAD_CREATE_DETACHED
pthread_detach() // 设置为detached thread
线程的取消
pthread_cancel() // 取消线程
线程被取消后,依然需要调用pthread_join 释放线程资源。被取消的线程,返回值是 PTHREAD_CANCELED.。
取消线程可能会带来 critial section 问题。线程的取消状态可以有两种:
1. synchronous cancelable:在Critical Section中不能取消
2. asynchronous cancelable:随时可以取消
pthread_setcanceltype() // 设置取消状态
pthread_setcancelstate() // 设置Critical Section
pthread_testcancel()
使用策略:尽量使用信号通知线程结束,而不是取消线程。
线程数据
相关类型、操作
pthread_key_t
pthread_key_create()
pthread_setspecific()
pthread_getspecific()
资源的自动释放
pthread_cleanup_push()
pthread_cleanup_pop()
线程 synchronization
多线程会引起 race condition 问题。未解决这个问题,必须是操作具有原子性。解决方法:
1. Mutex
pthread_mutex_t
pthread_mutex_init()
pthread_mutex_lock()
pthread_mutex_unlock ()
pthread_mutex_trylock()
Mutex有三种类型:
Fast:默认类型,如果同一个线程申请两次,会引起死锁;
Recursive:同一个线程可以申请多次;
error check:如果可能发生死锁,lock操作返回错误EDEADLK
pthread_mutexattr_t
pthread_mutexattr_init()
pthread_mutexattr_setkind_np()
2. semaphore
是一种计数信号量。
Semaphore.h
sem_t
sem_init()
sem_destroy().
sem_wait()
sem_trywait()
sem_post()
sem_getvalue()
3. condition variable
等待某个条件发生。
pthread_cond_t
pthread_cond_init()
pthread_cond_signal()
pthread_cond_broadcast()
pthread_cond_wait()
dead lock问题
多个线程对同一组资源进行操作,操作的顺序不同,将会引起死锁。
线程的实现
Linux用process实现线程。创建线程时,会生成一个管理进程。
信号的处理
pthread_kill() 在线程间发送信号
Fork 和 pthread_create 都是通过 clone 系统调用实现。
process 和 thread
提供了不同粒度的并行处理机制。
1. 执行的对象不同,Thread执行的同一个程序的不同部分,而process可以执行不同的程序。
2. 资源共享程度不同。Threads 运行在同一地址空间,数据共享容易,但是也带来了相互破坏内存数据的风险。
3. Process 需要IPC机制实现相互通信。