linux 5day
1.目录操作
目录操作分别为:
获取当前进程目录 修改当前进程目录 打开目录 关闭目录 创建目录 读取目录 创建目录
2.getcwd chdir获取(修改)当前进程的工作目录
#include <unistd.h>
char *getcwd(char *buf, size_t size);
功能:获取当前进程的工作目录
参数:
buf : 缓冲区,存储当前的工作目录
size : 缓冲区大小
返回值:
成功:buf中保存当前进程工作目录位置
失败:NULL1.
chdir函数
int main()
{
char u[32];
memset(u,0,32);
getcwd(u,80);//获取目录
printf("buf :%s\n",u);
//gb
int ret=-1;
ret=chdir("/home/deng");//改变目录
if(ret==-1)
{
perror("gect");
return 1;
}
getcwd(u,80);
printf("buf :%s\n",u);
return 0;
}
3.目录的打开和关闭
打开
int main()
{
DIR* dir=NULL;
dir=opendir("test");//打开目录
if(dir==NULL)
{
perror("jg");
return 1;
}
printf("dkmlcg\n");
//gbml
closedir(dir);//关闭目录
return 0;
}
4.目录的读取
相关结构体说明:
struct dirent
{
ino_t d_ino; // 此目录进入点的inode
off_t d_off; // 目录文件开头至此目录进入点的位移
signed short int d_reclen; // d_name 的长度, 不包含NULL 字符
unsigned char d_type; // d_type 所指的文件类型
char d_name[256]; // 文件名
};
d_type文件类型说明:
取值 | 含义 |
---|---|
DT_BLK | 块设备 |
DT_CHR | 字符设备 |
DT_DIR | 目录 |
DT_LNK | 软链接 |
DT_FIFO | 管道 |
DT_REG | 普通文件 |
DT_SOCK | 套接字 |
DT_UNKNOWN | 未知 |
5.目录文件读取
6.进程控制
1.wait 与waitpid 子进程结束问题
父进程->子进程完成某项工作 完成后需要释放资源 需要用到wait waitpid
区别wait会阻塞 waitpid不阻塞
1.wait
调用 wait() 函数的进程会挂起(阻塞),直到它的一个子进程退出或收到一个不能被忽视的信号时才被唤醒(相当于继续往下执行)。
若调用进程没有子进程,该函数立即返回;若它的子进程已经结束,该函数同样会立即返回,并且会回收那个早已结束进程的资源。
如果参数不为空 会把子进程的退出状态信息传递进去
int main()
{
pid_t pid;
int status;
pid=fork();
if(0==pid)
{
for(int i=0;i<5;i++)
{
printf("1\n");
sleep(1);
}
exit(10);
}
//堵塞在这里
wait(&status);
printf("1hszy\n");
return 0;
}
状态获取的使用
wait(&status);
if(WIFEXITED(status))
{
printf("5\n");
}
知识点
1.发送信号杀死进程 kill -9 进程号 信号是9
2.暂停和挂起 kill-19 kill-18 暂停和挂起
2.waitpid
waitpid(-1,&status,WNOHANG);
2.孤儿进程
父进程结束运行 但是子进程还在运行
内核就把孤儿进程的父进程设置为 init ,而 init 进程会循环地 wait() 它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init 进程就会代表党和政府出面处理它的一切善后工作。
3.僵尸进程
父进程卡着 子进程exit退出 但是没有用wait回收
如果大量的产生僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程,此即为僵尸进程的危害,应当避免。
4.进程替换
如果我们本来就运行着一个程序(进程),我们如何在这个进程内部启动一个外部程序,由内核将这个外部程序读入内存,使其执行起来成为一个进程呢?这里我们通过 exec 函数族实现。
只有execve()是真正的系统调用->其他都是在基础上进行封装的
exec 函数族的作用是根据指定的文件名或目录名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件。
exec 函数族使用说明
exec 函数族的 6 个函数看起来似乎很复杂,但实际上无论是作用还是用法都非常相似,只有很微小的差别。
补充说明:
l(list) | 参数地址列表,以空指针结尾 |
---|---|
v(vector) | 存有各参数地址的指针数组的地址 |
p(path) | 按 PATH 环境变量指定的目录搜索可执行文件 |
e(environment) | 存有环境变量字符串地址的指针数组的地址 |
exec 函数族与一般的函数不同,exec 函数族中的函数执行成功后不会返回,而且,exec 函数族下面的代码执行不到。只有调用失败了,它们才会返回 -1,失败后从原程序的调用点接着往下执行。
测试案例
execlp
execlp("ls","ls","-l","/home",NULL);
execl
execl("/bin/ls","ls","-l","/home",NULL);//可执行文件路径 可执行名字 参数 占位参数
无需掌握
int execv(const char *path, char *const argv[]);
char* argv[]={"ls","-l","/home",NULL};
execvp("/bin/ls",argv);
//---------------------------------------------
int execvp(const char *file, char *const argv[]);
char* argv[]={"ls","-l","/home",NULL};
execvp("ls",argv);
环境遍历包含
int execvpe(const char *file, char *const argv[], char *const envp[]);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步