精华内容
下载资源
问答
  • Linux C:多进程文件操作文件

    千次阅读 2016-10-19 21:07:46
    flock的用法是在打开文件后对文件读写前调用flock函数上锁,文件操作完后flock解锁,但需注意另一个进程操作同个文件时必须自己去检查文件是否已上锁,即在读写文件前调用flock函数即可进行判断,如果上锁,该进程则...

    flock函数可以锁定文件,避免多个进程对同个文件进行操作时出现数据出错。flock的用法是在打开文件后对文件读写前调用flock函数上锁,文件操作完后flock解锁,但需注意另一个进程操作同个文件时必须自己去检查文件是否已上锁,即在读写文件前调用flock函数即可进行判断,如果上锁,该进程则会阻塞,直到该文件被所占用的进程解锁。

    具体程序如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/file.h>
    
    #define MAX_SIZE 100
    
    int main()
    {
        FILE *fp;
    
        int i;
    
        char str[MAX_SIZE];
    
        fp = fopen("hello.txt","r");
    
        if(fp == NULL)
        {
            printf("open file error!\n");
            exit(1);
        }
    
        i = fileno(fp);
    
         if(-1 == flock(i,LOCK_EX))
         {
             printf("failing to lock!\n ");
         }
    
         if(0 == flock(i,LOCK_EX))
         {
             printf("lock success!\n");
         }
    
         fread(str,MAX_SIZE,1,fp);
    
         printf("%s\n",str);
    
         sleep(20);
    
         fclose(fp);
    
         flock(i,LOCK_UN);
    
        return 0;
    }
    


    展开全文
  • linux下多进程同时操作文件

    千次阅读 2015-07-14 15:51:19
    我们都知道多进程同时操作文件会出现问题,但是具体会出现什么问题呢?不知道大家有没有仔细研究过,今天我就带大家一起来研究一下。  在操作文件之前,很有必要了解一下内核中文件的存储和访问方式:  这张图...

            我们都知道多进程同时操作文件会出现问题,但是具体会出现什么问题呢?不知道大家有没有仔细研究过,今天我就带大家一起来研究一下。

         在操作文件之前,很有必要了解一下内核中文件的存储和访问方式:

          这张图摘自《APUE》,我觉得画的很好,所以就没有自己再画了。

           从图中能够看出每个进程都有自己独立的一个进程表项,由文件指针指向文件表项;在文件表项中两个很重要的东西:状态标志和当前文件偏移量,问什么说它很重要,因为在多进程写文件出错时,一般都是由文件偏移量引起的(这个后面会讲到);然后由V节点指针指向一个V节点表(关于i节点我会在另外的博客中阐述)

           第一种情况:父子进程同时写一个文件


          父进程再用fork函数创建子进程的时候,会把自己的上下文环境拷贝一份复制到子进程的内存空间中,这里当然包括进程表。所以子进程的进程表和父进程的是一模一样的,它们指向的是同一个文件表,上面讲到过,当前偏移量会引起文件操作错误。

          对于这个文件偏移量,有几点需要搞清楚:在用open函数打开文件时如果没有加上O_APPEND标志,那么这个文件表的文件偏移量为0;加上的话,它会把V节点中的当前文件长度赋给文件偏移量;写完文件之后(没有关闭文件描述符),文件长度会变化,相应的当前偏移量也随着文件长度的变化而变化。这里需要注意,是写完一个文件之后(也就是write函数执行完之后),便宜量才会改变。

         到这里的话,基本上就清楚了:如果写操作是一个原子操作的话(可以用pwrite实现),那么父子进程写同一个文件不会出现任何问题;如果不是原子操作的话,有可能在父进程的write函数没有返回之前又执行了子进程的write函数,由于当前文件偏移量没有改变,所以会覆盖掉原先内容。

          第二种情况:非父子进程写同一个文件

         

           对于非父子类型的多进程写同一个文件,其情况又是另外一回事了:

            进程各自有各自的进程表,至于为什么要有各自的进程表而不是共享一个进程表?可以这么想:各个进程打开文件的标志可能会不一样,有的可能只读、只写、或者读写方式,这样的话,它们中的内容肯定会不一样。

           对于fd0,假设它刚刚写完一个文件,fd0指向的文件表中的当前偏移量改变了,但是fd1中的偏移量没有改变,这就造成fd1在写文件时会覆盖fd0写入文件的内容。

          具体情况大家可以在自己的机器上试验一下。


           

    展开全文
  • LinuxLinux文件进程的关联

    千次阅读 2018-08-06 21:50:27
    由于操作系统要对系统所以进程提供服务,因此操作系统还要维护一个记录所有进程打开文件的总表。   进程与其打开文件的关系 如果说文件管理系统是文件的管理者与提供者,那么进程就是文件系统中文件的使用者。即...

    作为文件的使用者,进程理所当然地将要使用的文件记录于自己的控制块。另外,由于进程所对应的程序也是一个文件,因此进程控制块还必须记录这个文件的相关信息。由于操作系统要对系统所以进程提供服务,因此操作系统还要维护一个记录所有进程打开文件的总表。

     

    进程与其打开文件的关系

    如果说文件管理系统是文件的管理者与提供者,那么进程就是文件系统中文件的使用者。即,文件管理系统与进程之间是服务与客户之间的关系。

    文件对象

    当进程通过系统调用open()打开一个文件时,该系统调用找到这个文件后,会把文件封装到一个file结构的实例中提供给进程,这个实例称为file对象。

    file结构的定义如下:

    struct file {
    	union {
    		struct list_head	fu_list;        //所有打开文件的链表
    		struct rcu_head 	fu_rcuhead;
    	} f_u;
    	struct vfsmount     *f_vfsmnt;            //文件目录的VFS安装点指针
    	struct dentry     *f_dentry;            //文件的dentry
    #define f_dentry	f_path.dentry
    #define f_vfsmnt	f_path.mnt
    	const struct file_operations	*f_op;    //指向文件操作函数集的这孩子很
    	spinlock_t		f_lock;          /* f_ep_links, f_flags, no IRQ */
    	atomic_long_t		f_count;        //记录访问本文件的进程数目的计数器
    	unsigned int 		f_flags;        //访问类型
    	fmode_t			f_mode;            //访问模式
    	loff_t			f_pos;            //文件的当前读写位置
    	struct fown_struct	f_owner;
    	const struct cred	*f_cred;        //id信息
    	struct file_ra_state	f_ra;
    
    	u64			f_version;
    #ifdef CONFIG_SECURITY
    	void			*f_security;
    #endif
    	void			*private_data;
    
    #ifdef CONFIG_EPOLL
    	struct list_head	f_ep_links;
    #endif
    	struct address_space	*f_mapping;
    #ifdef CONFIG_DEBUG_WRITECOUNT
    	unsigned long f_mnt_write_state;
    #endif
    };

    其中,指针f_cred是记录文件所有者ID,文件所有者所在用户组ID的。其cred的结构如下:

    struct cred {
    	atomic_t	usage;
    	uid_t		uid;		/* real UID of the task */
    	gid_t		gid;		/* real GID of the task */
    	uid_t		suid;		/* saved UID of the task */
    	gid_t		sgid;		/* saved GID of the task */
    	uid_t		euid;		/* effective UID of the task */
    	gid_t		egid;		/* effective GID of the task */
    	uid_t		fsuid;		/* UID for VFS ops */
    	gid_t		fsgid;		/* GID for VFS ops */
    	unsigned	securebits;	/* SUID-less security management */
    	kernel_cap_t	cap_inheritable; /* caps our children can inherit */
    	kernel_cap_t	cap_permitted;	/* caps we're permitted */
    	kernel_cap_t	cap_effective;	/* caps we can actually use */
    	kernel_cap_t	cap_bset;	/* capability bounding set */
    #ifdef CONFIG_KEYS
    	unsigned char	jit_keyring;	/* default keyring to attach requested
    					 * keys to */
    	struct key	*thread_keyring; /* keyring private to this thread */
    	struct key	*request_key_auth; /* assumed request_key authority */
    	struct thread_group_cred *tgcred; /* thread-group shared credentials */
    #endif
    #ifdef CONFIG_SECURITY
    	void		*security;	/* subjective LSM security */
    #endif
    	struct user_struct *user;	/* real user ID subscription */
    	struct group_info *group_info;	/* supplementary groups for euid/fsgid */
    	struct rcu_head	rcu;		/* RCU deletion hook */
    };

    这就使得一个文件可能面临三种用户的访问:文件所有者、同组用户、其他用户。内核在处理一个进程或用户访问某一个文件的请求时,要根据进程的uid、fid和访问模式来确定该进程是否具有访问这个文件的权限。对于一个文件的用户来说,有读、写和执行三种文件操作,因此形成了三种权限,这三种权限与三种用户就共有9种组合,即文件的访问权限可以用9个二进制来表示,并将其保存在文件的dentry中。

    结构中的f_ops记录了进程对文件读写位置的当前值,它可以通过调用函数llseek()进行移动。

    值得注意的是,结构体中的指针f_op指向结构file_operations,该结构中封装了对于文件进行操作函数。该结构在文件include/linux/fs.h的定义如下:

    struct file_operations {
    	struct module *owner;
    	loff_t (*llseek) (struct file *, loff_t, int);
    	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
    	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    	ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
    	ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
    	int (*readdir) (struct file *, void *, filldir_t);
    	unsigned int (*poll) (struct file *, struct poll_table_struct *);
    	int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
    	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
    	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
    	int (*mmap) (struct file *, struct vm_area_struct *);
    	int (*open) (struct inode *, struct file *);
    	int (*flush) (struct file *, fl_owner_t id);
    	int (*release) (struct inode *, struct file *);
    	int (*fsync) (struct file *, struct dentry *, int datasync);
    	int (*aio_fsync) (struct kiocb *, int datasync);
    	int (*fasync) (int, struct file *, int);
    	int (*lock) (struct file *, int, struct file_lock *);
    	ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
    	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
    	int (*check_flags)(int);
    	int (*flock) (struct file *, int, struct file_lock *);
    	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
    	ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
    	int (*setlease)(struct file *, long, struct file_lock **);
    };

    从结构中可以看到,结构中是一系列函数的指针,这里有熟悉的read()、write()、open()、close()等函数的指针。进程就是通过调用这些函数来访问一个文件的,所以有人说file_operations结构是Linux虚拟文件系统与进程之间的主要接口。

    文件描述符

    弄清楚了系统管理file对象的方法之后,下面就进一步介绍每个进程对它自己访问的file对象的管理方法。

    Linux用一个数组来管理进程打开的文件的file对象,数组中的每一个元素都存放在一个指向进程所打开的文件的file对象。既然用一个数组来存放file对象,那么用数组的下标来访问文件就是一个顺理成章的方法,于是Linux就把数组元素的下标叫做该数组元素所对应的文件的文件描述符,该描述符就是系统对文件的标识,这个数组也叫做文件描述符数组,其示意图如下:

    内核通过调用系统调用函数dup()、dup2()和fctl()可以使数组中的多个元素指向同一个文件的file对象。也就是说,在Linux中,同一个文件可以有多个文件描述符。

    进程打开文件表

    前面看到,文件描述符数组中存放了一个进程所访问的所有文件,把这个文件描述符数组和这个数组在系统中的一些动态信息组合在一起,就会形成一个新的数据结构——进程打开文件表。

    进程打开文件表files_struct结构在文件include/linux/fdtable.h中的定义如下:

    struct files_struct {
    	atomic_t count;            //引用计数
    	struct fdtable *fdt;
    	struct fdtable fdtab;
    
    	spinlock_t file_lock ____cacheline_aligned_in_smp;
    	int next_fd;
    	struct embedded_fd_set close_on_exec_init;
    	struct embedded_fd_set open_fds_init;
    	struct file * fd_array[NR_OPEN_DEFAULT];        //文件描述符表指针
    };

    显然,这个结构应该属于进程的数据,所以进程控制块用指针files指向它。

    struct task_struct{
            ...
            struct files_struct *files;
            ...
    }

    进程与其打开文件之间的关系如下图所示:

    因为进程对于的程序也是一个文件,这个文件的位置在哪呢?

    进程在文件系统所在的位置叫做进程与文件系统的关系。Linux用结构fs_struct来描述进程在文件系统中的位置。结构fs_struct在文件include/linux.fs_struct.h中的定义如下:

    struct fs_struct {
    	int users;
    	rwlock_t lock;
    	int umask;
    	int in_exec; 
    	struct vfsmount *rootmnt, *pwdmnt, *altrootmnt;        //与安装有关的指针
    	struct dentry *root, *pwd, *altroot;           //与进程位置有关的指针
    };

    其中,pwd指向进程的当前所在目录;root指向进程的根目录;altroot是进程的替换目录。如下所示:

    另外三个指针rootmnt、pwdmnt和altrootmnt则对应地指向上面三个目录的结构vfsmount,该结构存放了目录的一些安装信息。

     

    系统打开和关闭文件表

    作为文件对象的提供者,操作系统必须对已经打开和使用过后已被关闭的文件进行记录。内核通过维护两个双向循环链表来管理这些被打开的文件和被关闭的文件:一个专门记录打开文件,另一个专门记录关闭文件。凡是file对象的f_count域不为NULL的文件,都被链入打开系统文件链表;而为NULL的文件,都被链入系统关闭文件链表。

    当VFS需要一个file对象时,将调用函数get_empty_file()优先在系统关闭文件链表中摘取,如果链表中file对象的数目已经为限制的底线NR_RESERVED_FILES,则系统就另行分配file对象所需要的内存空间。

     

    总结起来,就是:

     

    展开全文
  • 可以列出被进程所打开的文件信息。被打开的文件可以是: 1.普通的文件, 2.目录 3.网络文件系统的文件, 4.字符设备文件 5.(函数)共享库 6.管道,命名管道 7.符号链接 8.底层的socket字流,网络socket,unix域名...

    lsof命令是什么?
    可以列出被进程所打开的文件信息。被打开的文件可以是:
    1.普通的文件,
    2.目录
    3.网络文件系统的文件,
    4.字符设备文件
    5.(函数)共享库
    6.管道,命名管道
    7.符号链接
    8.底层的socket字流,网络socket,unix域名socket
    9.在linux里面,大部分的东西都是被当做文件的……还有其他很多

    怎样使用lsof
    这里主要用案例的形式来介绍lsof 命令的使用
    1.列出所有打开的文件:
    lsof
    备注: 如果不加任何参数,就会打开所有被打开的文件,建议加上一下参数来具体定位
    2. 查看谁正在使用某个文件
    lsof /filepath/file
    3.递归查看某个目录的文件信息
    lsof +D /filepath/filepath2/
    备注: 使用了+D,对应目录下的所有子目录和文件都会被列出
    4. 比使用+D选项,遍历查看某个目录的所有文件信息 的方法
    lsof | grep ‘/filepath/filepath2/’
    5. 列出某个用户打开的文件信息
    lsof -u username
    备注: -u 选项,u其实是user的缩写
    6. 列出某个程序所打开的文件信息
    lsof -c mysql
    备注: -c 选项将会列出所有以mysql开头的程序的文件,其实你也可以写成 lsof | grep mysql, 但是第一种方法明显比第二种方法要少打几个字符了
    7. 列出多个程序多打开的文件信息
    lsof -c mysql -c apache
    8. 列出某个用户以及某个程序所打开的文件信息
    lsof -u test -c mysql
    9. 列出除了某个用户外的被打开的文件信息
    lsof -u ^root
    备注:^这个符号在用户名之前,将会把是root用户打开的进程不让显示
    10. 通过某个进程号显示该进行打开的文件
    lsof -p 1
    11. 列出多个进程号对应的文件信息
    lsof -p 123,456,789
    12. 列出除了某个进程号,其他进程号所打开的文件信息
    lsof -p ^1
    13 . 列出所有的网络连接
    lsof -i
    14. 列出所有tcp 网络连接信息
    lsof -i tcp
    15. 列出所有udp网络连接信息
    lsof -i udp
    16. 列出谁在使用某个端口
    lsof -i :3306
    17. 列出谁在使用某个特定的udp端口
    lsof -i udp:55
    特定的tcp端口
    lsof -i tcp:80
    18. 列出某个用户的所有活跃的网络端口
    lsof -a -u test -i
    19. 列出所有网络文件系统
    lsof -N
    20.域名socket文件
    lsof -u
    21.某个用户组所打开的文件信息
    lsof -g 5555
    22. 根据文件描述列出对应的文件信息
    lsof -d description(like 2)
    23. 根据文件描述范围列出文件信息
    lsof -d 2-3

    链接:https://www.jianshu.com/p/c06ea5e548ec

    展开全文
  • linux下多进程/多线程文件操作详解

    万次阅读 2016-07-24 20:18:37
    内核使用三种数据结构表示打开的文件,它们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响 1.每个进程进程表都有一个记录项,记录项中包含有一张打开文件描述符表,与文件描述符相关联的是: ...
  • id查看用户信息 查看用户的信息 # 查看自己的信息 id # 查看指定的用户信息 id 用户名 查看文件的所有者 查看进行的操作
  • linux 查看进程文件句柄

    千次阅读 2009-06-29 22:16:00
    http://hi.baidu.com/gniwan/blog/item/edafb2cb171b904ef31fe753.html 其中 "open files (-n) 1024 "是Linux操作系统对一个进程打开的文件句柄数量的限制(也包含打开的SOCKET数量,可影响MySQL的并发连接数目)....
  • 查看这个进程的内容,我们首先得找到这个东西,下面就是根据进程名称查找所在目录的方法:linux进程运行后,进程信息存储在/proc/进程id 目录下面,进程id查看命令 ps -ef | grep 进程名,vi /proc/进程id/...
  • Linux进程读写文件 文件

    千次阅读 2015-07-07 14:30:33
    目前遇到一个问题:多个进程对同一个文件进行写操作,如何避免冲突。研究了一下,做个小结。   对于多进程文件,主要有以下两种处理方式: 1.类似于Linux日志文件服务 启动一个logger进程,其他进程...
  • linux 查看进程命令

    千次阅读 2020-02-10 17:55:56
    Linux 查看进程之PS命令 要对进程进行检测和控制,首先必须... ps(process status) 命令是 Linux 下最常用的进程查看工具,使用该命令可以确定哪些进程正在运行和运行的状态、 进程是否结束、进程有没有僵尸、哪...
  • ...lsof(list open files)是一个列出当前系统...在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP)
  • linux查看某个进程打开的文件

    千次阅读 2019-12-25 17:47:38
    今天在处理一个问题的时候,涉及到查看某个进程打开的文件数,在此记录下. 操作过程: 1.查看进程号 [deploy@ningbo-dev-55 mizar-account]$ jps | grep web 32568 meteor-connector-web-4.8.0-SNAPSHOT.jar [deploy@...
  • Linux文件系统操作命令、进程调用命令 1.Linux文件系统操作命令
  • 如何查看进程打开了哪些文件?---linux下的proc文件系统 分类: Linux操作系统2011-10-10 17:06 594人阅读 评论(0) 收藏 举报 procfs是一种伪文件系统。 记录了系统运行时的所有内核信息和配置信息。...
  • 关于linux进程打开同一文件操作的一点分析 按照系统的设计,每个进程自己维护一张打开表  索引 文件描述符 文件指针  0 close_on_exec 0x.....  ............. 然后内核会维护一张表,这个表表示...
  • linux查看进程所有子进程和线程

    万次阅读 2018-08-28 14:58:42
    linux查看进程所有子进程和线程 原文连接:https://blog.csdn.net/uestczshen/article/details/74091892   问题: 我的程序在其内部创建并执行了多个线程,我怎样才能在该程序创建线程后监控其中单个线程?我想...
  • Linux进程文件访问权限

    千次阅读 2013-08-31 22:05:21
    介绍linux进程文件访问权限
  •  有许多情况下,我们需要查看一个进程当前打开了哪些文件,反过来我们也希望知道某一个文件正在被哪些进程所读写。在Linux下有许多有用的工具可以帮我们完成这两个工作,下面介绍这两个工具:lsof与fuser。  ...
  • Linux根据进程查看进程位置

    万次阅读 2015-05-01 21:01:15
    Linux的所有进程都保存在/proc/目录下,保存形式为:/proc/进程号。进入到进程号目录后,里面有一个cwd链接文件即指向的进程的的目录。 2) 操作: A:确定进程号。如:4874; B:查找进程执行的文件。ps aux | grep...
  • 【Linux】Linux进程的创建与管理

    万次阅读 多人点赞 2018-07-27 19:21:29
    在Linux系统中,除了系统启动之后的第一个进程由系统来创建,其余的进程都必须由已存在的进程来创建,新创建的进程叫做子进程,而创建子进程的...Linux进程创建的过程示意图如下所示:   子进程的创建 在Li...
  • linux查看进程

    千次阅读 2019-05-21 00:16:23
    查看进程树 1)以用户zhangsan登入,完成下列操作 2)使用vim打开abc.txt文件,不要编辑、不退出 3)以用户root登入另一个终端,完成下列操作 4)查看整个系统的进程树,输出PID号、完整命令行 5)查找用户zhangsan的进程...
  • 关键字: linux进程、杀进程、起进程进程 ps 命令查找与进程相关的PID号: ps a 显示现行终端机下的所有程序,包括其他用户的程序。 ps -A 显示所有程序。 ps c 列出程序时,显示每个程序真正的指令名称,而...
  • LINUX 查看进程

    千次阅读 2019-05-21 17:23:06
    4)查看整个系统的进程树,输出PID号、完整命令行 5)查找用户zhangsan的进程树 6)查找用户zhangsan的进程树,并显示PID与完整命令 方案 PID:既标识了一个进程,也说明了这个进程启动的顺序。 程序:保存在磁盘中的可...
  • Linux查看某个进程的线程

    千次阅读 2018-10-30 10:22:11
    当一个程序内有多个线程被叉分出用以执行多个流时,这些线程就会在它们之间共享特定的资源(如,内存地址空间、打开的文件),以使叉分开销最小化,并避免大量高成本的IPC(进程间通信)通道。这些功能让线程在并发...
  • Linux 查看进程

    千次阅读 2019-05-23 15:59:53
    4)查看整个系统的进程树,输出PID号、完整命令行 5)查找用户zhangsan的进程树 6)查找用户zhangsan的进程树,并显示PID与完整命令 方案 PID:既标识了一个进程,也说明了这个进程启动的顺序。 程序:保存在磁盘...
  • Linux如何查看进程、杀死进程、启动进程等常用命令
  • linux查看进程实例详解

    万次阅读 2017-11-11 17:44:11
    说明:本文所有案例均在linux 2.6.32-642.el6.x86_64验证成功 查看进程 ps (重要) Process State 是非常强大的进程查看命令,用于报告当前系统的进程状态。 常用选项: 1、BSD风格 a——和终端有关的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 537,730
精华内容 215,092
关键字:

linux查看哪些进程操作文件

linux 订阅