美文网首页
dirent,进程,僵尸

dirent,进程,僵尸

作者: 萌面大叔2 | 来源:发表于2017-02-15 13:06 被阅读0次

    在文件指定位置插入数据而不覆盖

    #include <stdio.h>
    #include <string.h>  //strerror
    #include <errno.h>  //errno
    #include <unistd.h>  //read write
    /*open*/
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    #define PER_IO_BYTES 4096
    
    int main(int argc, char *argv[])
    {
        char caFile[64] = {'\0'};
        strncpy(caFile, argv[1], sizeof(caFile));
        
        int ret = -1;
        strcat(caFile, ".old");
        ret = rename(argv[1], caFile);
        if (-1 == ret)
        {
            printf("rename error:%s\n", strerror(errno));
            return -1;
        }
    
        int fdNew = -1;
        fdNew = open(argv[1], O_WRONLY | O_CREAT
                     , S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
        if (-1 == fdNew)
        {
            printf("open error:%s\n", strerror(errno));
            return -1;
        }
        int fdOld = -1;
        fdOld = open(caFile, O_RDONLY);
        if (-1 == fdOld)
        {
            printf("open error:%s\n", strerror(errno));
            return -1;
        }
    
        off_t offset = 0;
        printf("please input position:");
        scanf("%ld", &offset);
        char caBuf[PER_IO_BYTES] = {'\0'};
        int iLeft = offset;
        //将指定位置之前的数据拷贝到新文件中
        while (iLeft)
        {
            if (iLeft >= PER_IO_BYTES)
            {
                ret = read(fdOld, caBuf, PER_IO_BYTES);
            }
            else
            {
                ret = read(fdOld, caBuf, iLeft);
            }
            if (-1 == ret)
            {
                printf("read error:%s\n", strerror(errno));
                break;
            }
            iLeft -= ret;
            ret = write(fdNew, caBuf, ret);
            if (-1 == ret)
            {
                printf("write error:%s\n", strerror(errno));
                break;
            }
        }
    
        //在指定的位置写入数据
        char *pData = "$$$qwertyuiopasdfghjklzxcvbnm$$$";
        ret = write(fdNew, pData, strlen(pData));
        if (-1 == ret)
        {
            printf("write error:%s\n", strerror(errno));
            return;
        }
    
        //将指定位置之后的数据写入新文件中  
        while (1)
        {
            ret = read(fdOld, caBuf, PER_IO_BYTES);
            if (-1 == ret)
            {
                printf("read error:%s\n", strerror(errno));
                break;
            }
            else if (0 == ret)
            {
                break;
            }
            ret = write(fdNew, caBuf, ret);
            if (-1 == ret)
            {
                printf("write error:%s\n", strerror(errno));
                break;
            }
        }
    
        close(fdNew);
        close(fdOld);
    
        ret = remove(caFile);
        if (-1 == ret)
        {
            printf("remove error:%s\n", strerror(errno));
            return -1;
        }
    
        return 0;
    }
    
    

    测试文件是否存在(可读可写可执行)

    #include <unistd.h>
    #include <stdio.h>  //perror
    
    //mode:
    //    F_OK:测试文件是否存在
    //    R_OK:测试用户是否对文件具有可读权限
    //    W_OK:测试用户是否对文件具有可写权限
    //    X_OK:测试用户是否对文件具有可执行权限
    //测试用户对于指定的文件是否具有mode权限
    //如果有,则函数返回0
    //否则返回-1
    //int access(const char *pathname, int mode);
    
    int main(int argc, char *argv[])
    {
        int ret = -1;
        //ret = access(argv[1], F_OK);
        //ret = access(argv[1], R_OK | W_OK);
        ret = access(argv[1], X_OK);
        if (-1 == ret)
        {
            perror("access");
            return -1;
        }
        else if (0 == ret)
        {
            printf("user has those permissions\n");
        }
    
        return 0;
    }
    

    判断文件类型(普通文件,目录文件)

    #include <stdio.h>
    #include <string.h>
    /*stat()*/
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    /*opendir()*/
    #include <sys/types.h>
    #include <dirent.h>
    
    int main(int argc, char *argv[])
    {
        DIR *pDir = opendir(argv[1]);
        if (NULL == pDir)
        {
            perror("opendir:");
            return -1;
        }
        printf("opendir ok\n");
        struct dirent *pDirent = NULL;
        struct stat fileStat;
        int ret = -1;
        pDirent = readdir(pDir);
        int iRegNum = 0;
        int iDirNum = 0;
        int iOthNum = 0;
        while (NULL != pDirent)
        {
            printf("%s\n", pDirent->d_name);
            ret = stat(pDirent->d_name, &fileStat);
            if (0 == ret)
            {
                switch (fileStat.st_mode & S_IFMT)
                {
                case S_IFREG:
                    iRegNum++;
                    break;
                case S_IFDIR:
                    iDirNum++;
                    break;
                default:
                    iOthNum++;
                    break;
                }
            }
            else if (-1 == ret)
            {
                perror("stat");
                break;
            }
            pDirent = readdir(pDir);
        }
        printf("普通的文件:%d个.\n", iRegNum);
        printf("目录的文件:%d个.\n", iDirNum);
        printf("其他类型的文件:%d个.\n", iOthNum);
    
        closedir(pDir);
    
        return 0;
    }
    

    1.进程的命令

    查看CPU:top
    查看所有的进程:ps -A
    查看当前的进程:ps
    关闭进程:kill -9 进程id
    创建进程:fork

    父进程,子进程(fork)

    #include <unistd.h>   //fork()
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        pid_t pid = -1;
        int iNum = 0;
        char caData[32] = {'\0'};
        //子进程创建后,和父进程属于两个相互独立的进程
        //父进程调用fork,这是一个系统调用,因此进入内核
        //内核根据父进程复制出一个子进程,父子进程的PCB信息相同
        //用户态代码和数据也完全相同。
        //因此,子进程现在的状态看起来和父进程一样,做完了初始化
        //刚调用了fork进入内核,还没有从内核返回。
        //现在有两个一模一样的进程看起来都调用了fork进入内核等待
        //从内核返回(实际上fork只调用了一次)。此外系统中还有其他
        //进程等待从内核返回。是父进程先返回还是子进程先返回,还是
        //父子进程都等待,其他进程先返回,这是不确定的。
        //取决于内核的调度算法
        pid = fork();
        //fork成功:将子进程的id返回给父进程的pid变量
        //          将0返回给子进程的pid变量
        //    失败:返回-1给父进程的pid变量,子进程不会被创建   
        //          并且错误号会被设置
        if (pid > 0)  //父进程
        {
            printf("this is parent process\n");
            strcpy(caData, "this is parent process\n");
            iNum = 3;
        }
        else if (0 == pid)  //子进程
        {
            printf("this is child process\n");
            strcpy(caData, "this is child process\n");
            iNum = 6;
        }
        else if (-1 == pid)  //创建进程失败
        {
            perror("fork");
            return -1;
        }
        int i = 0;
        for (; i < iNum; i++)
        {
            printf("%s", caData);
            sleep(1);   
        }
    
        printf("Hello World\n");
        return 0;
    }
    

    僵尸进程

    #include <unistd.h>   //fork()
    #include <stdio.h>
    #include <string.h>
    //一个进程结束时会关闭所有的文件描述符,
    //释放在用户空间分配的内存,
    //但它的PCB还保留着,
    //如果进程异常终止则保留着导致该进程终止的信号
    //如果正常终止则保留退出状态:在终端可以用“$?”来查看
    //父进程可以调用wait或waitpid获取这些信息,
    //然后彻底清楚掉这个进程
    
    //如果一个进程终止,但是其父进程尚未调用wait或者waitpid
    //对他进行清理,这时的进程状态称之为僵尸进程。
    
    //任何进程在刚终止的时候都是僵尸进程,
    //正常情况下僵尸进程会立刻被父进程清理。
    
    //僵尸进程的危害:
    //    系统允许存在的进程数是有上限的。
    //    若存在大量的僵尸进程,则可能创建新的进程由于没有
    //    进程号分配而失败
    
    
    //形成僵尸进程实例:
    int main(void)
    {
        pid_t pid = -1;
        pid = fork();
        if (pid > 0)  //父进程
        {
            printf("this is parent process\n");
            while (1)
            {}
        }
        else if (0 == pid)  //子进程
        {
            printf("this is child process\n");
            return 0;
        }
        else if (-1 == pid)  //创建进程失败
        {
            perror("fork");
            return -1;
        }
    
        printf("Hello World\n");
        return 0;
    }
    

    处理僵尸进程

    #include <unistd.h>   //fork()
    #include <stdio.h>
    #include <string.h>
    /*waitpid()*/
    #include <sys/types.h>
    #include <sys/wait.h>
    
    //僵尸进程的处理方式
    //1,将子进程的善后处理交给祖宗进程(父进程不方便对子进程清理)
    //   A-->B-->C: 将B进程挂掉,那么C进程的清理工作由祖宗进程来做
    //2,父进程自己调用相应函数来对子进程做善后处理
    //   调用wait()或者waitpid()
    int main(void)
    {
        pid_t pid = -1;
        pid = fork();
        if (pid > 0)  //父进程
        {
            printf("this is parent process\n");
            //阻塞等待子进程的结束
            //获得子进程的退出状态,并对子进程做清理工作
            wait(NULL);
            while (1)
            {}
        }
        else if (0 == pid)  //子进程
        {
            printf("this is first child process\n");
            pid_t pid2 = fork();
            if (pid2 > 0)
            {
                return 0;
            }
            else if (0 == pid2)
            {
                int i = 0;
                for (; i < 3; i++)
                {
                    printf("this is second child process\n");
                }
                return 0;
            }
            
        }
        else if (-1 == pid)  //创建进程失败
        {
            perror("fork");
            return -1;
        }
    
        printf("Hello World\n");
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:dirent,进程,僵尸

          本文链接:https://www.haomeiwen.com/subject/kubtmttx.html