美文网首页上嵌学习笔记
系统与网络编程-(dir,进程)

系统与网络编程-(dir,进程)

作者: I踏雪寻梅 | 来源:发表于2016-11-30 21:27 被阅读9次

    系统与网络编程

    access使用

    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc,char *argv[])
    {
        int ret=-1;
        ret=access(argv[1],F_OK);
        if(ret==-1)
        {
            perror("access");
            return -1;
        }
        else if(ret==0)
        {
            printf("file exist\n");
        }
        return 0;
    }
    //111已存在,222无
    
    
    Paste_Image.png
    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc,char *argv[])
    {
        int ret=-1;
        ret=access(argv[1],W_OK|R_OK);
        if(ret==-1)
        {
            perror("access");
            return -1;
        }
        else if(ret==0)
        {
            printf("file exist\n");
        }
        return 0;
    }
    //查看用户可执行权限
    
    
    Paste_Image.png

    dir

    • opendir:打开指定的
    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <dirent.h>
    int main(int argc,char *argv[])
    {
        //打开指定的目录,打开失败返回NULL.成功则返回指向目录的指针.
        DIR *pDir=(opendir(argv[1]));
        if(pDir==NULL)
        {
            perror("opendir:");
            return -1;
        }
        printf("opendir ok\n");
        close (pDir);
        return 0;
    }
    
    Paste_Image.png
    • readdir:读取目录下的内容
    int main(int argc,char *argv[])
    {
        //打开指定的目录,打开失败返回NULL.成功则返回指向目录的指针.
        DIR *pDir=(opendir(argv[1]));
        if(pDir==NULL)
        {
            perror("opendir:");
            return -1;
        }
        printf("opendir ok\n");
        struct dirent *pDirent=NULL;
        pDirent = readdir(pDir);
        while(pDirent!=NULL)
        {
            printf("%s ",pDirent->d_name);
            pDirent=readdir(pDir);
            //readdir(pDir)每次都会获得目录里的信息
        }
        printf("\n");
        close (pDir);
    }
    
    Paste_Image.png
    • rewinddir(pDirent):返回到目录的头部
    • mkdir(pathname,mode):创建一个目录
    • rmdir(pDirent):删除一个目录
    • stat:查看目标文件目录下的文件及属性
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <dirent.h>
    int main(int argc,char *argv[])
    {
        //打开指定的目录,打开失败返回NULL.成功则返回指向目录的指针.
        DIR *pDir=(opendir(argv[1]));
        if(pDir==NULL)
        {
            perror("opendir:");
            return -1;
        }
        printf("opendir ok\n");
        struct stat fileStat;
        struct dirent *pDirent=NULL;
        int ret=-1;
        pDirent = readdir(pDir);
        while(pDirent!=NULL)
        {
            printf("%s ",pDirent->d_name);
            ret=stat(pDirent->d_name,&fileStat);
            if(ret==0)
            {
                switch(fileStat.st_mode&S_IFMT)
                {
                    case S_IFREG:printf("这是一个普通文件\n");break;
                    case S_IFDIR:printf("这是一个目录文件\n");break;
                    default:printf("其他类型的文件\n");break;
                }
            }
            else if(ret==-1)
            {
                perror("stat");
                break;
            }
            pDirent=readdir(pDir);
            //readdir(pDir)每次都会获得目录里的信息
        }
        printf("\n");
        closedir(pDir);
        
    }
    
    Paste_Image.png

    进程

    1. 什么是进程
      • 进程是操作系统结构的基础;是一个正在执行的 程序 ;计算机中正在运行的程序实例;可以分配给 处理器 并由处理器执行的一个实体;由单一顺序的执行显示,一个当前状态和一组相关的系统资源所 描述 的活动单元。
    2. 进程控制块
    3. 进程和程序的区别
      • 程序生存期很长,进程运行开始到运行结束。程序可以开启多个进程,但是一个进程只对应一个程序。
    4. 查看进程的运行状态
      • top
    5. 如何查看正在运行的进程
      • ps:当前终端由用户启动的进程
      • ps-a:系统后台所有的进程
    6. 如何创建进程
      • fork:父进程创建子进程,父进程会对子进程进行一次拷贝,其中使用的资源都会完全的拷贝一份。返回状态也会被拷贝一份到子进程。
      • 子进程id返回给父进程,父进程传给子进程数值0,父进程若得到-1,说明子进程未成功执行
      • ./xxx &后台运行
    7. 进程如何结束
      • kill -9 +num
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    int main(void)
    {
        pid_t pid=-1;
        pid=fork();
        if(pid>0)//父进程
        {
            printf("this is parent progress\n");    
        }
        else if(pid==0)//子进程
        {
            printf("this is child progress\n"); 
        }
        else if(pid=-1)//创建进程失败
        {
            perror("fork");
            return -1;
        }
        while(1)
        {}
        printf("hello world\n");
        return 0;
    }
    
    Paste_Image.png
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    int main(void)
    {
        pid_t pid=-1;
        int iNum=0;
        char caData[32]={'\0'};
        //子进程创建后,与父进程属于两个相互独立的进程.
        pid=fork();
        //fork成功:将子进程的id返回给父进程的PID,将0返回子进程的pid,
        //fork失败:返回-1给父进程的pid变量,子进程便不会被创建
        if(pid>0)//父进程
        {
            printf("this is parent progress\n");    
            strcpy(caData,"this is parent progress\n");
            iNum=3;//父进程执行3次,当结束时会显示终端~/1612/11/11.30....
        }
        else if(pid==0)//子进程
        {
            printf("this is child progress\n"); 
            strcpy(caData,"this is child progress\n");
            iNum=6;
        
        }
        else if(pid=-1)//创建进程失败
        {
            perror("fork");
            return -1;
        }
        int i=0;
        for(;i<iNum;i++)
        {
            printf("%s",caData);
            sleep(1);
        }
        printf("hello world\n");
        return 0;
    }
    
    Paste_Image.png
    • 僵尸进程:子进程挂了但是父进程很忙,导致子进程被杀死后无人收拾<defunct>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    int main(void)
    {
        pid_t pid=-1;
        pid=fork();
        if(pid>0)//父进程
        {
            printf("this is parent progress\n");    
            while(1)
            {}
        }
        else if(pid==0)//子进程
        {
            printf("this is child progress\n"); 
        }
        else if(pid=-1)//创建进程失败
        {
            perror("fork");
            return -1;
        }
        while(1)
        {}
        printf("hello world\n");
        return 0;
    }
    
    Paste_Image.png
    • 僵尸进程
      • 如果一个进程终止,但是其父进程尚未调用wait或者waitpid,对他进行清理,这时的进程状态称之为僵尸进程。任何进程在刚终止的时候都是僵尸进程,正常情况下僵尸进程会立刻被父进程清理。
      • 僵尸进程的危害:
        1. 系统允许存在的进程数是有上限的。
        2. 若存在大量的僵尸进程,则可能创建新的进程由于没有
        3. 进程号分配而失败
    • 僵尸进程处理方式
      1. 将子进程的善后处理方式交给祖宗进程处理
        • A-->B-->C:将B进程kill,C进程将会交给祖宗进程来清理。
      2. 父进程自己调用响应函数来对子进程做善后处理
      #include <unistd.h>
      #include <stdio.h>
      #include <string.h>
      #include <sys/types.h>
      #include <sys/wait.h>
      int main(void)
      {
          pid_t pid=-1;
          pid=fork();
          if(pid>0)//父进程
          {
              printf("this is parent progress\n");    
              wait(NULL);//阻塞等待子进程的结束,获得子进程的退出状态,并对子进程做出清理工作.
              while(1)
              {}
          }
          else if(pid==0)//子进程
          {
              printf("this is first child progress\n");   
              pid_t pid2=-1;
              pid=fork();
              if(pid2>0)
              {
                  return 0;
              }
              else if(pid2==0)
              {
                  printf("this is second child progress\n");  
                  return 0;
              }
              else if(pid=-1)//创建进程失败
              {
                  perror("fork");
                  return -1;
              }
          }
          else if(pid=-1)//创建进程失败
          {
              perror("fork");
              return -1;
          }
          return 0;
      }
      
    Paste_Image.png Paste_Image.png
    • 编程实现每一秒钟父进程向文件中写入信息,每一秒子进程显示文件大小。
    #include <stdio.h>
    #include <errno.h>  //errno  
    #include <string.h>  //strerror()
    #include <unistd.h>  //read()  write()
    /*open*/
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    int main(int argc,char *argv[])
    {
        pid_t pid=-1;
        pid=fork();
        int i=0;
            if(pid>0)//父进程
            {
                int fd=-1;  
                fd=open(argv[1],O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP);
                
                if(fd==-1)
                {
                    printf("open error:%s\n",strerror(errno));
                    return -1;
                }
                    char *pData="hello world";
                while(1)
                {
                #if 1
                    write(fd,pData,strlen(pData));
                    printf("insert success\n");
                    sleep(1);
                #endif
                }
                    close(fd);
            }
            else if(pid==0)//子进程
            {
                int fd=-1;  
                fd=open(argv[1],O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP);
                    off_t offset=-1;
                while(1)
                {
                #if 1
                    offset=lseek(fd,0,SEEK_END);
                    if(offset==-1)
                    {
                        printf("lseek error:%s\n",strerror(errno));
                    }
                    else
                    {
                        printf("file size:%ld\n",offset);
                    }
                    sleep(1);
                #endif
                }
                    close(fd);
            }
            else if(pid=-1)//创建进程失败
            {
                perror("fork");
                return -1;
            }       
        return 0;
    }
    
    • 一个进程结束时会关闭所有的文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,如果进程异常终止则保留着导致该进程终止的信号
    • 如果正常终止则保留退出状态:在终端可以用“$?”来查看
    • 父进程可以调用wait或waitpid获取这些信息,然后彻底清楚掉这个进程

    homework

    • 实现将目标目录下的目录及统统拷贝
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    //open stat
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>//read() write()
    //dir
    #include <dirent.h>
    #include <stdlib.h>
    #define PER_IO_BYTES 4096
    //拷贝文件需要考虑目录文件及文本文件
    
    int fileType(mode_t mode)//获得文件类型
    {
        int ret =-1;
        switch(mode & S_IFMT)//S_IFMT:掩码,可获得该文件类型
        {
            case S_IFREG:
                ret=0;
                break;
            case S_IFDIR:
                ret=1;
                break;
            default:
                ret=-1;
                break;
        }
        return ret;
    }
    void copyRegularFile(const char *pDestPathname,
                        const char *pSrcPathname)//拷贝普通文件
    {
        if(pDestPathname==NULL||pSrcPathname==NULL)//形参有效性检查
        {
            return;
        }
        int iDestFd=-1;//以写的方式打开目标文件
        iDestFd=open(pDestPathname,O_WRONLY|O_CREAT,
                     S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
        if(iDestFd==-1)
        {
            perror("open dest");
            exit(EXIT_FAILURE);//文件返回状态
        }
        int iSrcFd=-1;//以读的方式打开源文件
        iSrcFd=open(pSrcPathname,O_RDONLY|O_CREAT,
                     S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
        if(iSrcFd==-1)
        {
            perror("open src");
            exit(EXIT_FAILURE);//文件返回状态
        }
        unsigned char caBuf[PER_IO_BYTES]={'\0'};
        int ret=-1;
        //从源文件循环读取数据
        while(ret=read(iSrcFd,caBuf,PER_IO_BYTES))
        {
            //判断数据读取成功失败与否
            if(ret==-1)
            {
                //如果发生的错误是EGAIN,EGAIR
                //需要重新读取数据
                if(errno=EAGAIN||errno==EINTR)
                {
                    continue;
                }
                //如果是其他错误,则显示信息并退出程序
                perror("read src");
            //  close(iSrcFd);
            //  close(iDestFd);
                exit(EXIT_FAILURE);//文件返回状态
            }
            //如果返回值为0,表示已读到文件尾,没有数据可读
            //则文件拷贝结束
            else if(ret==0)
            {
                break;
            }
            while(1)
            {   //将读到的数据写入到目标文件
                ret=write(iDestFd,caBuf,ret);
                if(ret==-1)
                {
                    if(errno=EAGAIN||errno==EINTR)
                    {
                        continue;
                    }
                    perror("write dest");
            //      close(iSrcFd);
            //      close(iDestFd);
                    exit(EXIT_FAILURE);
                }
                break;
            }
        }
        close(iSrcFd);
        close(iDestFd);
    }
    
    void copyDirFile(const char *pDestDirName
                     , const char *pSrcDirName)
    {
        if (NULL == pDestDirName || NULL == pSrcDirName)
        {
            return;
        }
        int ret = -1;
        ret = mkdir(pDestDirName, 0775);
        if (-1 == ret)
        {
            if (EEXIST != errno)
            {
                perror("mkdir");
                exit(EXIT_FAILURE);
            }
        }
        DIR *pDestDir = NULL;
        pDestDir = opendir(pDestDirName);
        if (NULL == pDestDir)
        {
            perror("open dest dir");
            exit(EXIT_FAILURE);
        }
        DIR *pSrcDir = NULL;
        pSrcDir = opendir(pSrcDirName);
        if (NULL == pSrcDir)
        {
            perror("open src dir");
            exit(EXIT_FAILURE);
        }
        char caDestFileName[64] = {'\0'};
        char caSrcFileName[64] = {'\0'};
        struct stat fileStat;
        struct dirent *pDirent = NULL;
        pDirent = readdir(pSrcDir);
        int iLen = 0;
        while (NULL != pDirent)
        {
            if (0 != strcmp(pDirent->d_name, "..")
                && 0 != strcmp(pDirent->d_name, "."))
            {
                strcpy(caSrcFileName, pSrcDirName);
                iLen = strlen(pSrcDirName);
                if (pSrcDirName[iLen-1] != '/')
                {
                    strcat(caSrcFileName, "/");
                }
                strcat(caSrcFileName, pDirent->d_name);
                printf("%s\n", caSrcFileName);
    /********************************************************/
                strcpy(caDestFileName, pDestDirName);
                iLen = strlen(pDestDirName);
                if (pDestDirName[iLen-1] != '/')
                {
                    strcat(caDestFileName, "/");
                }
                strcat(caDestFileName, pDirent->d_name);
    /********************************************************/
                ret = stat(caSrcFileName, &fileStat);
                if (-1 == ret)
                {
                    perror("stat");
                    exit(EXIT_FAILURE);
                }
                ret = fileType(fileStat.st_mode);
                switch (ret)
                {
                case 0:
                    copyRegularFile(caDestFileName, caSrcFileName);
                    break;
                case 1:
                    copyDirFile(caDestFileName, caSrcFileName);
                    break;
                default:
                    break;
                }
            }
    /********************************************************/
            pDirent = readdir(pSrcDir);
        }
    }
    
    int main(int argc,char *argv[])
    {
        copyDirFile(argv[2],argv[1]);   
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:系统与网络编程-(dir,进程)

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