linux调用线程的命令 linux线程相关函数( 二 )


__pthread_manager()就是管理线程的主循环所在,在进行一系列初始化工作后,进入while(1)循环 。在循环中,线程以2秒为 timeout查询(__poll())管理管道的读端 。在处理请求前 , 检查其父线程(也就是创建manager的主线程)是否已退出 , 如果已退出就退出 整个进程 。如果有退出的子线程需要清理,则调用pthread_reap_children()清理 。
然后才是读取管道中的请求 , 根据请求类型执行相应操作(switch-case) 。具体的请求处理 , 源码中比较清楚 , 这里就不赘述了 。
3.线程栈
在LinuxThreads中 , 管理线程的栈和用户线程的栈是分离的,管理线程在进程堆中通过malloc()分配一个THREAD_MANAGER_STACK_SIZE字节的区域作为自己的运行栈 。
用户线程的栈分配办法随着体系结构的不同而不同,主要根据两个宏定义来区分,一个是NEED_SEPARATE_REGISTER_STACK,这个属 性仅在IA64平台上使用;另一个是FLOATING_STACK宏,在i386等少数平台上使用,此时用户线程栈由系统决定具体位置并提供保护 。与此同 时 , 用户还可以通过线程属性结构来指定使用用户自定义的栈 。因篇幅所限,这里只能分析i386平台所使用的两种栈组织方式:FLOATING_STACK 方式和用户自定义方式 。
在FLOATING_STACK方式下,LinuxThreads利用mmap()从内核空间中分配8MB空间(i386系统缺省的最大栈空间大?。?果有运行限制(rlimit),则按照运行限制设置),使用mprotect()设置其中第一页为非访问区 。该8M空间的功能分配如下图:
图4 栈结构示意
低地址被保护的页面用来监测栈溢出 。
对于用户指定的栈,在按照指针对界后,设置线程栈顶 , 并计算出栈底 , 不做保护,正确性由用户自己保证 。
不论哪种组织方式 , 线程描述结构总是位于栈顶紧邻堆栈的位置 。
4.线程id和进程id
每个LinuxThreads线程都同时具有线程id和进程id , 其中进程id就是内核所维护的进程号,而线程id则由LinuxThreads分配和维护 。
在Linux系统中使用Shell实现多线程运行任务(多任务并发执行) 2022-05-30 最近,有一批任务需要把两批的fastq合并到一起并压缩成一个fastq文件才能继续往下做,由于存储空间有限又不能直接全部跑上,只能按样本逐个分批跑 。众所周知,一般fastq是成对存在的 , 所需要对read1和read2分别合并一次,然而这次任务的fastq文件比较大,合并然后压缩一次需要1天左右,那对于一组fastq就要2-3天,这也太耗时间了,所以我在想能不能read1和read2 同时跑上,这就可以节省一半的时间了 。
平时也能遇到很多类似的任务,特别是在进程数有限的情况下,如果这些小任务单独占用一个进程 , 而任务很多就很耗时间,如果能在一个进程下实现多个线程并行执行,就能大大提高运行效率 。关于进程和线程的知识可以参考知乎的这篇文章【 Shell“ 多线程”,提高工作效率 】,整理的也比较有条理,能比较容易读懂 。
当然,某些博主也写过类似的文章 , 例如这篇【 shell后台限制多并发控制后台任务强度进行文件拷贝 】但是实在是太高深莫测了,看不懂 , 一时半会儿也学不会 。本文将示例Shell实现多线程的简单版本,其实不用太复杂 。
其实只需要两个步骤, 第一步是给需要并行运行的命令行在结尾加上"" , 代表放到后台运行,第二步是在在所有并行任务的后面加上一句“wait”,意思是等所有通过“”放到后台运行的任务跑完后再继续执行后面的任务  , 这些就能实现所有带有“”的行并行执行了 。

推荐阅读