Linux环境编程05

七、目录操作
    int mkdir(const char *pathname, mode_t mode);
    功能:创建目录
    mode:目录的权限,注意必须要有执行权限,否则无法进入

    int rmdir(const char *pathname);
    功能:删除空目录

    int chdir(const char *path);
    功能:进入某个目录,相当于cd命令

    char *getcwd(char *buf, size_t size);
    功能:获取当前工作目录,相当于pwd命令

    DIR *opendir(const char *name);
    功能:打开目录文件,返回一个目录流
    name:选择要打开的目录

    struct dirent *readdir(DIR *dirp);
    功能:从目录流中读取一条记录
    struct dirent {
            ino_t          d_ino;       // i节点号
            off_t          d_off;       // 下一条条目的偏移值
            unsigned short d_reclen;    // 当前条目的长度
            unsigned char  d_type;      // 文件类型

                DT_BLK      块设备文件
                DT_CHR      字符设备文件
                DT_DIR      目录文件
                DT_FIFO     管道文件
                DT_LNK      链接文件
                DT_REG      普通文件
                DT_SOCK     socket文件
                DT_UNKNOWN  未知类型
            char d_name[256]; // 文件名
            };

    练习1:ls -l

    void seekdir(DIR *dirp, long loc);
    功能:设置目录流的位置指针,用于随机读取

    void rewinddir(DIR *dirp);
    功能:设置目录流的位置指针到开头 

    long telldir(DIR *dirp);
    功能:获取当前目录流的位置指针位置

    作业:
        实现 rm -rf 功能(建议备份虚拟机、重点关注. .. 两个目录的删除)

信号处理:

基本概念:
    1、中断
        当进程接收到信息后中止当前正在执行的进程,转而去执行其它任务,等其它任务完成后再返回,这种执行模式叫做中断模式。
        中断分为硬件中断和软件中断。
    2、信号
        是一种软件中断,由操作系统发出,进程接收后会执行相应的操作
    3、常见的信号
        kill -l 显示出所有的信号
        SIGINT(2)   ctrl+c          终止
        SIGQUIT(3)  ctrl+\          终止+core
        SIGFPE(8)   除0             终止+core 
        SIGKILL(9)  终止信号        终止 
        SIGSEGV(11) 非法访问内存    终止+core 
    4、不可靠信号和可靠信号
        建立在早期的信号处理机制上的信号(1~31),是不可靠信号
        不支持排队,可能会丢失信号,同一个信号如果连续产生多次,进程可能只处理了一次
        建立在新的信号处理机制上的信号(34~64),是可靠信号 
        支持排队,不会丢失的
    5、信号来源
        硬件异常:除0、无效的内存访问、未定义的指令、总线错误
        软件异常:一般通过命令、函数产生的信号
    6、信号的处理方式
        1、忽略
        2、终止进程
        3、终止并产生core文件
        4、捕获并处理信号
            (在信号来之前,向内核注册一个信号函数,当信号发生后,系统会自动执行注册函数)
        
信号捕获:
    #include <signal.h>

    typedef void (*sighandler_t)(int);
    功能:信号处理函数的格式,必须尊循

    sighandler_t signal(int signum, sighandler_t handler);
    功能:向内核注册一个绑定某个信号的信号处理函数
    signum:信号编号
    handler:函数指针
        除了直接给函数名外,还可以给以下参数:
            SIG_IGN 忽略
            SIG_DFL 按默认方式处理
    返回值:
        之前的信号处理方式

    注意:
        1、一个函数可以同时绑定多个信号
        2、个别系统通过signal注册的函数只能执行一次,如果想要持续有效,可以在信号处理函数中再重新注册一次
        3、信号处理完后会返回产生信号的代码处继续执行,如果我们捕获并处理了段错误、算术异常等信号,可能会产生死循环,
        因此正确地处理段错误、算数异常应该是备份数据并结束进程
        4、子进程会继承父进程的信号处理方式

    连习2:测试一下(1-31) 哪些信号不能被捕获处理
    #include <sys/types.h>
    #include <signal.h>
    int kill(pid_t pid, int sig);
    kill函数
    9 19号信号不能被捕获也不能被忽略

信号的发送:
    键盘:
        Ctrl+c 
        Ctrl+\
        Ctrl+z  暂停\挂起   命令fg唤醒
    错误:
        除0
        非法内存访问
        硬件错误、总线错误
    命令:
        kill -信号 进程号
        killall -信号 进程名    
            可以向同名的多个进程发送同一个信号
    函数:
        int kill(pid_t pid, int sig);
        功能:向指定进程发送指定信号
        pid:进程号
        sig:信号编号 

        int raise(int sig);
        功能:向进程自己发送信号sig

        void abort(void);
        功能:向自己发送SIGABRT信号

        unsigned int alarm(unsigned int seconds);
        功能:让内核在seconds秒后向调用者发送SIGALRM信号
        返回值:上一次alarm设置的剩余秒数
        注意:如果再次调用时,会覆盖之前的设置,按照新的设置定时,因此不会产生多次闹钟信号

进程休眠信号:
    int pause(void);
    功能:让调用者进入休眠状态,直到进程遇到信号
    返回值:要么一直休眠不返回,要么返回-1
    相当于没有时间限制的sleep

    unsigned int sleep(unsigned int seconds);
    功能:让调用者进入休眠指定的秒数,当遇到信号时会提前返回
    返回值:剩余没睡的秒数

信号集与信号阻塞:
    信号集:是一种数据类型,可以存储多个信号
            sigset_t 128位的数,每一位代表了一个信号
    相关函数:
        int sigemptyset(sigset_t *set);
        功能:清空信号集

        int sigfillset(sigset_t *set);
        功能:填满信号集

        int sigaddset(sigset_t *set, int signum);
        功能:向信号集中添加一个信号

        int sigdelset(sigset_t *set, int signum);
        功能:从信号集中删除一个信号

        int sigismember(const sigset_t *set, int signum);
        功能:测试在信号集中是否存在某个信号
        返回值:
            0   不存在
            1   存在
            -1  信号非法

    信号阻塞:
        当程序执行一下特殊的操作时是不适合处理信号的,此时可以让内核先屏蔽信号,等操作执行结束后再继续发送处理信号
        当信号发生时,内核会在其维护的信号表中为进程设置一个与该信号对应的标志位,该过程叫做递送
        从信号产生到最终完成发送是有一个时间间隔,处于该间隔的信号状态叫做未决
        信号阻塞就是让信号处于未决状态,暂停发送,当屏蔽解除后信号可以继续发送
        每个进程都有一个信号集专门用于存储需要屏蔽的信号

    int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
    功能:设置要屏蔽的信号,这些屏蔽的信号存储在进程内部的信号集中
    how:信号屏蔽的方式
        SIG_BLOCK       把set中的信号添加到要屏蔽的信号集中
        SIG_UNBLOCK     从信号集中删除set的信号
        SIG_SETMASK     用set替换原来的屏蔽信号集中的信号
    set:准备好的信号集         输入型参数
    oldset:获取旧的信号屏蔽集  输出型参数  不接可以给NULL

定时器:
    #include <sys/time.h>

    int getitimer(int which, struct itimerval *curr_value);
    功能:获取当前的定时方案
    which:选择一个计时器
        ITIMER_REAL     真实计时器  程序总的执行时间        SIGALRM 
        ITIMER_VIRTUAL  虚拟计时器  用户态的执行时间        SIGALRM
        ITIMER_PROF     实际计时器  用户态+内核态的执行时间 SIGPROF

        真实计时器 = 实际计时器 + 休眠时间 + 切换时间
    

    int setitimer(int which, const struct itimerval *new_value,
                     struct itimerval *old_value);
    功能:设置新的定时方案
        struct itimerval {
            struct timeval it_interval; // 每次时钟信号产生的间隔时间
            struct timeval it_value;    // 第一次时钟信号产生的时间
        };

        struct timeval {
            time_t      tv_sec;         // 秒
            suseconds_t tv_usec;        // 微秒 一百万分之一秒
        };
        注意:如果tv_usec的值超过一秒以上,方案失效


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值