
线程浅析
发布日期:2021-05-08 05:59:33
浏览次数:21
分类:精选文章
本文共 1368 字,大约阅读时间需要 4 分钟。
线程的基本属性
每个线程都包含有表示执行环境所必需的信息,包括进程中标识线程的线程id,一组寄存器器值,栈,调度优先级和策略,信号屏蔽字,error变量以及线程私有数据。一个进程的所有信息对该进程的所有线程都是共享的,包括代码段,静态区,堆,栈以及文件描述符。
线程部分函数
以下是常见的线程函数及其用途:
int pthread_equal(pthread_t tid1, pthread_t tid2);
:比较两个线程id是否相等,相等返回非0数值,否则返回0。pthread_exit
:用在子线程中,结束当前子线程。pthread_t pthread_self(void)
:用在子线程中,获取线程id。pthread_attr_init
:设置pthread_attr_t
结构体属性(如堆栈大小、调度优先级、分离状态等),必须在pthread_create
之前调用。pthread_attr_destroy
:对应于pthread_attr_init
,释放资源。int pthread_create
:第一个参数是线程id取地址,第二个参数是pthread_attr_t*
,第三个参数是函数指针,第四个参数是入参指针。int pthread_cancel(pthread_t tid);
:用来请求取消同一进程中的其他线程。
pthread_join和pthread_detach
线程在任何一个时间点上都可以是可结合的(joinable)或分离的(detached)。可结合的线程能够被其他线程回收其资源和杀死,存储器资源在被回收前保持不释放。分离的线程则无法被回收或杀死,其存储器资源在其终止时由系统自动释放。
默认情况下,线程被创建成可结合的。为了避免存储器泄漏,需要通过pthread_join
显式回收或调用pthread_detach
分离线程。
pthread_join
:使主线程等待该线程结束后才结束,避免主线程快速结束而导致资源未被释放。pthread_detach
:在线程中调用,使线程脱离主线程,确保资源在线程终止时由系统自动释放。
多线程中使用fork
先回顾fork函数
通过fork
创建的子进程几乎与父进程相同,但有以下区别:
- 子进程获得与父进程相同的用户级虚拟地址空间拷贝。
- 子进程获得与父进程相同的文件描述符拷贝。
- 子进程有独立的PID。
多线程中使用fork的问题
在多线程环境中,fork
的行为会引发一系列问题:
- 除了调用
fork
的线程外,其他线程在子进程中“蒸发”了。 - 处理锁和共享资源时可能导致死锁。
exec与文件描述符
exec
函数族用于替换进程的内容段。为了避免锁问题,建议在fork
后立即调用exec
,这样可以避免锁复制问题,但限制了后续操作。
pthread_atfork函数
pthread_atfork
提供了一个解决方案:
prepare
:父进程在fork
前解锁所有锁。parent
:父进程在fork
返回前重新锁上所有锁。child
:子进程在fork
返回前解锁所有锁。
这种方式允许多个锁处理程序注册,确保锁的正确层次管理,但需要谨慎处理条件变量。
总结
在多线程程序中,最好只使用fork
执行exec
函数,避免对fork
出的子进程进行其他操作,以减少锁相关问题的风险。