Linux文件共享(五)——线程共享文件

注:转载请注明出处   作者:lvyilong316

4.1 Linux线程实现

在谈论线程之间共享文件之前,我想首先简单的介绍下linux线程的实现。最初的进程定义都包含程序、资源及其执行三部分,其中程序通常指代码,资源在操作系统层面上通常包括内存资源、IO资源、信号处理等部分,而程序的执行通常理解为执行上下文,包括对cpu的占用,后来发展为线程。在线程概念出现以前,为了减小进程切换的开销,操作系统设计者逐渐修正进程的概念,逐渐允许将进程所占有的资源从其主体剥离出来,允许某些进程共享一部分资源,例如文件、信号,数据内存,甚至代码,这就发展出轻量进程的概念。Linux内核在2.0.x版本就已经实现了轻量进程,应用程序可以通过一个统一的clone()系统调用接口,用不同的参数指定创建轻量进程还是普通进程。在内核中,clone()调用经过参数传递和解释后会调用do_fork(),这个核内函数同时也是fork()、vfork()系统调用的最终实现:在do_fork()中,不同的clone_flags将导致不同的行为,对于LinuxThreads,它使用(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)参数来调用clone()创建"线程",表示共享内存、共享文件系统访问计数、共享文件描述符表,以及共享信号处理方式。(其中前三个标志对应共享的数据结构分别为task_struct中的mm,fs,files)。

(1) CLONE_VM

    do_fork()需要调用copy_mm()来设置task_struct中的mm和active_mm项,这两个mm_struct数据与进程所关联的内存空间相对应。如果do_fork()时指定了CLONE_VM开关,copy_mm()将把新的task_struct中的mm和active_mm设置成与current的相同,同时提高该mm_struct的使用者数目(mm_struct::mm_users)。也就是说,轻量级进程与父进程共享内存地址空间。

(2) CLONE_FS(这个和我们接下来的讨论有关)

    task_struct中利用fs(struct fs_struct *)记录了进程所在文件系统的根目录和当前目录信息,do_fork()时调用copy_fs()复制了这个结构;而对于轻量级进程则仅增加fs->count计数,与父进程共享相同的fs_struct。也就是说,轻量级进程没有独立的文件系统相关的信息,进程中任何一个线程改变当前目录、根目录等信息都将直接影响到其他线程。

(3) CLONE_FILES(这个和我们接下来的讨论也有关)

    一个进程可能打开了一些文件,在进程结构task_struct中利用files(struct files_struct *)来保存进程打开的文件结构(struct file)信息,do_fork()中调用了copy_files()来处理这个进程属性;轻量级进程与父进程是共享该结构的,copy_files()时仅增加files->count计数。这一共享使得任何线程都能访问进程所维护的打开文件,对它们的操作会直接反映到进程中的其他线程。

(4) CLONE_SIGHAND

每一个Linux进程都可以自行定义对信号的处理方式,在task_struct中的sig(struct signal_struct)中使用一个struct k_sigaction结构的数组来保存这个配置信息,do_fork()中的copy_sighand()负责复制该信息;轻量级进程不进行复制,而仅仅增加signal_struct::count计数,与父进程共享该结构。也就是说,子进程与父进程的信号处理方式完全相同,而且可以相互更改。

4.2 线程打开文件分析

    有了以上分析,我们就可以画出线程间对应的打开文件数据结构的关系,如下图所示。

    我们看到,线程间所有文件结构都为共享资源,不但“文件表项”(file对象)是共享的,就连“文件描述符表”(files_struct结构)也是共享的。

    总结:线程的创建仅仅增加的是files和fs的引用计数,“文件打开计数”(file对象的引用计数)并没有增加,所以任何一个线程对打开的文件执行close操作,文件都将关闭(文件打开计数为1的情况)。但是如果线程不进行打开文件的关闭,则文件直到进程结束时才会关闭,这就是使用多线程实现tcp服务器时,服务线程必须要显示调用close的原因,否则永远不会发送FIN终止链接(因为主线程一直处于监听不会结束)。

时间: 2024-11-18 09:52:45

Linux文件共享(五)——线程共享文件的相关文章

Linux文件共享(一)——进程与打开文件

Linux支持在不同进程间共享打开文件.为了说明文件共享,先来说明内核用于所有I/O的数据结构. 他们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响. 0.1和文件有关的对象 (1) inode(i节点): 保存一个文件的通用信息,每个inode有一个inode number,在文件系统中,一个inode number能够唯一地标识一个文件. (2) dentry(目录项对象):每个dentry代表路径中的一个特定部分.保存一个目录的链接信息.个人理解:描述一个文件和一个名字的

Linux进程和线程的基础与管理

  一.进程的基本概念 程序是为了完成某种任务而设计的软件,比如vi是程序.什么是进程呢? 进程就是运行中的程序.一个运行着程序,可能有多个进程.比如Web服务器是Apache服务器,当管理员启动服务后,可能会有好多人来访问,也就是说许多用户同时请求httpd,Apache服务器将会创建多个httpd进程来对其进行服务. 首先我们看看进程的定义.进程是一个具有独立功能的程序关于某个数据集合的一次可以并发执行的运行活动,是处于活动状态的计算机程序.进程作为构成系统的基本细胞,不仅是系统内部独立运行

Linux文件共享(六)——描述符传递

注:转载请注明出处   作者:lvyilong316 5.1 进程间描述符传递 首先,我们先来讨论一个问题--进程间传递文件描述符究竟传递的是什么? 我们从传递描述符函数的参数来看是个fd,我们知道fd是打开文件指针的在数组中的下标,是一个整数,那么我们仅仅是把一个整数传递给另一个进程吗?答案肯定是否定的,因为仅仅是传递整数值,没有必要专门去实现一个api.至于深层次的的原因,我们可以想一下,假如接受进程仅仅收到的是一个整数值,他能知道什么,又能做什么呢?即使它知道这是来自另一个进程的一个打开文

linux下创建线程内存泄漏,php的json

  这次还是把遇到的几个问题整理一下,希望再遇到的同学能轻松解决.另外最近博客的feeds延迟更新的原因也会一起说明一下. 1.linux下创建线程导致内存泄漏 今天在外网发布了一个server之后,用top发现virt的使用量一直在涨,而且一次涨8m.于是可以断定有内存泄漏了,经过排查,最终确定原因出在多线程的问题上: 代码如下: 1 2 3 4 5 6 pthread_t thread_id; int ret=pthread_create(&thread_id, NULL, flush_th

在Linux中使用线程

我并不假定你会使用Linux的线程,所以在这里就简单的介绍一下.如果你之前有过多线程方面的编程经验,完全可以忽略本文的内容,因为它非常的初级. 首先说明一下,在Linux编写多线程程序需要包含头文件pthread.h.也就是说你在任何采用多线程设计的程序中都会看到类似这样的代码: #include 当然,进包含一个头文件是不能搞定线程的,还需要连接libpthread.so这个库,因此在程序连接阶段应该有类似这样的指令: gcc program.o -o program -lpthread.h>

linux 把主线程cancel 掉后,由主线程创建的子线程会不会被cancel掉?

问题描述 linux 把主线程cancel 掉后,由主线程创建的子线程会不会被cancel掉? linux 把主线程cancel 掉后,由主线程创建的子线程会不会被cancel掉? 解决方案 不会.进程是独立的,不是线程.

linux crontab 五分钟一次调用,会不会很不好?这个文件需要查询和修改数据库,请问可行吗

问题描述 linux crontab 五分钟一次调用,会不会很不好?这个文件需要查询和修改数据库,请问可行吗 五分钟一次调用,会不会很不好?这个文件需要查询和修改数据库,请问可行吗 求大神指点 解决方案 主要看系统负载以及你的脚本执行消耗的资源等. 解决方案二: 如果你的脚本执行数据库,很快就可以执行完,应该没问题的.如果数据库查询和修改需要很长时间,比如超过五分钟,前一次还没执行完,就要执行下一次,肯定要出问题.数据库优化也很重要. 解决方案三: 如果你的脚本执行数据库,很快就可以执行完,应该

Linux 进程、线程运行在指定CPU核上

/******************************************************************************** * Linux 进程.线程运行在指定CPU核上 * 说明: * affinity参数决定了进程.线程是否可在CPU多核之间切换,当然,并不是说就不进行 * 线程切换. * * 2017-9-22 深圳 龙华樟坑村 曾剑锋 *********************************************************

linux虚拟机与winodows共享文件夹----linux安装VMware tools

虚拟机里面想要获取原来本机 系统的文件,十分麻烦.为了实现原系统与虚拟机的共享文件夹,可以通过安装vmware tools达到共享目的. 1 安装vmware tools (1)检查虚拟机上是否挂载了光驱,如果已经挂载先unmount (2)解压vmwaretools压缩包 复制vmwaretools中的gz压缩包到自己的文件夹下(任意,自己能找到就行) 然后解压压缩包使用 tar -xzvf vmware------*.gz 命令 按照提示输入ENTER进行确认即可 2 进行共享文件夹设置 在