系统编程基础(二)
1、系统文件IO和标准文件IO的区别
标准文件IO只读写普通文件和二进制文件 fread()fwrite()fopen()fclose()fseek() 系统文件IO还可以读写系统设备文件 read()write()open()close()lseek() 对于特殊的文件比如管道,socket只能用read,write读写 标准文件IO读写时使用缓冲区,系统文件IO不使用缓冲区
- 2、系统文件IO文件拷贝
- 3、lseek
- 4、access函数
#include <unistd.h>
int access(const char *pathname, int mode);
/*
pathname文件名或绝对路径文件名
mode:
F_OK判断文件是否存在
R_OK是否可读
W_OK是否可写
X_OK是否可执行
返回值成功返回0,错误返回-1
*/
- 5、文件属性
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
返回值成功返回0,出错返回-1
struct stat
{
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */ /* 文件保护模式 */
nlink_t st_nlink; /* number of hard links 硬链接数*/
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes 文件的大小*/
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
/*
S_ISREG(m) is it a regular file?是否是普通文件?
S_ISDIR(m) directory? 目录?
S_ISCHR(m) character device? 字符设备?
S_ISBLK(m) block device? 块设备?
S_ISFIFO(m) FIFO? 管道?
S_ISLNK(m) symbolic link? 链接文件?
S_ISSOCK(m) socket? socket?
S_IFMT 0170000 文件类型的位掩码
S_IFMT & buf.st_mode
S_IFSOCK 0140000 socket
S_IFLNK 0120000 链接文件
S_IFREG 0100000 规则文件
S_IFBLK 0060000 块设备文件
S_IFDIR 0040000 目录
S_IFCHR 0020000 字符设备文件
S_IFIFO 0010000 管道
*/
- 6文件目录读写函数
//①opendir()
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
//②readdir()
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
struct dirent
{
ino_t d_ino; /* inode number */
off_t d_off; /* not an offset; see NOTES */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported by all filesystem types */
char d_name[256]; /* filename */
};
//③closedir()
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
- 7读取文件属性相关的函数
//①getpwuid用户id
#include <sys/types.h>
#include <pwd.h>
struct passwd *getpwuid(uid_t uid);
char *pw_name;
struct passwd
{
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
har *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
//②getgrgid用户所属组id
#include <sys/types.h>
#include <grp.h>
struct group *getgrgid(gid_t gid);
char *gr_name;
struct group
{
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* group members */
};
//③localtime
#include <time.h>
struct tm *localtime(const time_t *timep);
struct tm
{
int tm_sec; /* seconds */
int tm_min; /* minutes */
int tm_hour; /* hours */
int tm_mday; /* day of the month */
int tm_mon; /* month */
int tm_year; /* year */
int tm_wday; /* day of the week */
int tm_yday; /* day in the year */
int tm_isdst; /* daylight saving time */
};
//④readlink链表的链接的源文件名
#include <unistd.h>
ssize_t readlink(const char *path, char *buf, size_t bufsiz);
//path链接文件名
//buf源文件名
8、进程
什么是进程 进程是系统中分配资源的最小单位 查看进程 ps -aux查看系统中所有进程 ps -ef查看当前用户的进程 ps -efl查看当前用户的进程详情
9进程控制块
进程id 进程队列 信号量 文件 内存 虚拟内存 cpu类型 SMP对称多处理器 errno
10进程状态
主要的五个状态:创建 运行 就绪 阻塞 退出 运行时三个状态:运行 就绪 阻塞 就绪->运行 运行->就绪 运行->阻塞 阻塞->就绪 但是阻塞不能到运行 阻塞需要通过就绪转化到运行
- 11进程的生成函数fork
#include <unistd.h>
pid_t fork(void);
fork()调用一次有两个返回值,父进程返回的是子
进程的pid,子进程返回是0,出错时返回值小于0
为什么父进程返回值是子进程的pid?
因为子进程是父进程生成的,父进程需要管理子进程,
没有直接获取子进程的pid函数需要知道子进程的pid号
为什么子进程返回值是0?
因为子进程本身的pid可以通过函数getpid()获取
没有直接获取子进程的pid的函数
getpid()//获取自己的pid号
getppid()//获取父进程的pid号
12、fork生成子进程的过程
fork生成子进程后,子进程是对父进程的完整拷贝 拷贝的资源包括: 代码,堆栈,文件描述符,信号量集 如果文件加锁文件锁是不拷贝的,信号量集拷贝到 子进程后,子进程中的信号量集清空
13、vfork函数
vfork函数是先从父进程拷贝能够运行的最小的资源的集合 写时拷贝技术:在运行的时候根据程序运行需要的资源,再 从父进程拷贝 vfork函数是先运行子进程,再运行父进程
14僵尸进程和孤儿进程
僵尸进程: 对于父子进程,如果子进程先退出,因为子进程是由 是由于子进程是由父进程生成的,父进程中总有子进 程没有及时给子进程善后那么,这时的子进程称为僵 尸进程。 孤儿进程: 对于父子进程,如果父进程先退出了,这时候子进程 init进程的进程号pid是1
15、进程的pid
是一个unsigned short型的整数 0~65535 但是我们一般定义取值范围是0~32767 内核进程的pid是0 init进程的pid是1 pstree查看进程树