线程浅析
发布日期: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出的子进程进行其他操作,以减少锁相关问题的风险。

上一篇:线程池
下一篇:多线程同步

发表评论

最新留言

感谢大佬
[***.8.128.20]2025年04月22日 19时04分07秒