• C语言_文件_进程_进程间通讯 常用函数/命令 + 实例


    .md带目录版:http://t.csdnimg.cn/jlpQa 

    文件相关命令:

    1. ps -aux|grep init? //搜索包含init名称的进程
    2. top //linux下的资源管理器(动态)
    3. //open 返回的int 是给后面的读/写/光标移动 用的fd,没有open就不能进行后面的操作;
    4. int open(const char *pathname, int flags);
    5. int open(const char *pathname, int flags, mode_t mode);
    6. close(fd); //关闭文件
    7. // _t 都是返回的int数字;写write,读read,光标移动lseek
    8. ssize_t write(int fd, const void *buf, size_t count);
    9. ssize_t read(int fd, void *buf, size_t count);
    10. off_t lseek(int fd, off_t offset, int whence);
    11. //同时打开两个文件
    12. vimdiff demo1.c demo2.c
    13. //fopen注意mode就行,有:r r+ w w+ a ,返回的文件指针是给后面的读 写 偏移用
    14. FILE *fopen(const char *pathname, const char *mode);
    15. fclose(FILE *); //关闭文件
    16. //跟上面的差不多一样用
    17. //fread/fwrite(读写的数组,读写的大小, 读写的最大次数?, 读写的文件指针)
    18. (读写返回次数的区别:读为有效次数,能一次读完就算你写10次,也返回只读1次)
    19. size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    20. size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
    21. int fseek(FILE *stream, long offset, int whence);
    22. fputc();//写入一个字符;
    23. fgetc();//读取一个字符
    24. feof();/检测是否到达文件末尾,到了返回1;文件结束符为EOF=-1;
    25. //注意:读写操作都会使光标偏移,但也可以利用这点来遍历读写文件;
    26. 例:
    27. while(!feof(FILE* fd)){
    28. printf("%c ",fgetc(FILE* fd));
    29. }

    进程相关命令:

    getpid(); fork(); vfork();

    1. //_t 一律返回的是int
    2. //获取进程ID 就是pid
    3. pid_t getpid(void);
    4. //fork创建子进程
    5. pid_t fork(void);
    6. //这里返回的是的pid = 0 就是子进程,pid > 0 就是父进程;
    7. //所以可以通过判断pid的值,来区别父子进程需要执行的代码;
    8. //注意fork开辟的子进程,没有等待一说,父子进程谁抢到就先运行谁,
    9. //【子进程为僵尸进程】;
    10. //例:
    11. #include
    12. #include
    13. #include
    14. #include
    15. int main()
    16. {
    17. pid_t pid;
    18. int num = 0;
    19. pid = getpid();
    20. printf("this pid:%d\n",getpid());
    21. pid_t return_pid = fork();
    22. if(return_pid > 0){
    23. while(1){
    24. printf("this father pid:%d return_pid:%d \n",getpid(),return_pid);
    25. printf("father now num:%d\n",num);
    26. sleep(1);
    27. }
    28. }else if(return_pid == 0){
    29. printf("this son pid:%d return_pid:%d \n",getpid(),return_pid);
    30. num += 2;
    31. printf("child now num:%d\n",num);
    32. exit(6);
    33. }
    34. }
    35. //vfork创建子进程
    36. pid_t vfork(void);
    37. //注意fork开辟的子进程,会等待子进程执行完并exit(num)后,父子进程才继续执行,
    38. //【子进程不会成为僵尸进程】;
    39. //例:
    40. #include
    41. #include
    42. #include
    43. #include
    44. int main()
    45. {
    46. pid_t pid;
    47. pid = getpid();
    48. printf("this pid:%d\n",getpid());
    49. int num = 0;
    50. printf("start_father_num:%d \n",num);
    51. pid_t return_pid = vfork();
    52. if(return_pid > 0){
    53. while(1){
    54. printf("this father pid:%d return_pid:%d \n",getpid(),return_pid);
    55. printf("num = %d\n",num);
    56. sleep(1);
    57. }
    58. }
    59. else if(return_pid == 0){
    60. int i;
    61. for(i=0;i<3;i++){
    62. printf("this son pid:%d return_pid:%d \n",getpid(),return_pid);
    63. num++;
    64. sleep(1);
    65. }
    66. exit(0);
    67. }
    68. return 0;
    69. }

    exit(6);            wait(status);   WEXITSTATUS(status); 

    子进程退出;  等待子进程; 获取子进程退出状态码;

    1. //wait() 返回的是子进程的ID 即pid;
    2. //里面的 int *status 是子进程的exit(num)的num码;
    3. //后续使用WEXITSTATUS(status),即可打印出来子进程退出时的状态码;
    4. pid_t wait(int *status);
    5. //例:
    6. #include
    7. #include
    8. #include
    9. #include
    10. int main()
    11. {
    12. pid_t pid;
    13. int status = 0;
    14. pid = getpid();
    15. printf("start father pid:%d\n",getpid());
    16. pid_t return_pid = fork();
    17. if(return_pid > 0 ){
    18. pid_t child_pid = wait(&status);
    19. printf("\n\nwait_return_childe_pid:%d\n",child_pid);
    20. printf("child exit code:%d \n",WEXITSTATUS(status));
    21. while(1){
    22. printf("this father pid:%d fork_return_pid:%d > 0 \n",getpid(),return_pid);
    23. sleep(1);
    24. }
    25. }else if(return_pid == 0){
    26. int i;
    27. for(i=0;i<3;i++){
    28. printf("this son pid:%d fork_return_pid:%d == 0 \n",getpid(),return_pid);
    29. }
    30. exit (6);
    31. }
    32. return 0;
    33. }

    exec组函数 对比 system + popen :(程序/进程跳转)

    大佬精彩博文: https://blog.csdn.net/u014530704/article/details/73848573

    观后感:

    跟着execl/execlp指定的程序跑了,不回来了!

    1. // date 获取时间的程序
    2. execl("./PATH","date","NULL");
    3. // execl(程序所在路径,程序名,结尾必须为NULL)
    4. // 就像这样用,在当前程序运行到这句代码时,
    5. // 便将替换为后续执行execl所指的程序,不带回头的那种!
    6. execlp("date","date",NULL);
    7. // execlp(程序名,程序名,结尾必须为NULL)
    8. // 就像这样用,它带p,能自己在环境变量下搜索对应的程序并替换后续执行;
    9. // 也是不带回头的那种!

    相比较之下 system 执行完指定程序后,还会回来,挺好!

    1. system("cat demo1.c");
    2. //执行完成后返回原程序,继续执行后续代码;

    而对比popen 而言,popen除了将指定程序/代码执行完之后,继续执行后续代码外,还将读/写的内容放在管道内,并以文件指针的形式返回;

    1. #include
    2. #include
    3. int main()
    4. {
    5. printf("------------------------------------------------\nPS:\n");
    6. char* p = "ps";
    7. FILE *fd = popen(p,"r");
    8. char data[1024];
    9. fread(&data,1024,1,fd);
    10. printf("%s\n",data);
    11. perror("why");
    12. return 0;
    13. }

    进程间通讯:

    int pipe(int pipefd[2]);  (无名管道,在文件里看不到) 

    里面的fd[2]数组,其中 fd[0] : 读的fd, fd[1] : 写的fd;

    例:通过在父子进程中 close  (fd[0]/fd[1])  配合read(); write(); 实现进程间通讯;

    1. #include
    2. #include
    3. #include
    4. #include
    5. int main()
    6. {
    7. printf("------------------------------------------------:\n");
    8. int fd[2];
    9. int n_pipe = pipe(fd);
    10. char data1[128];
    11. if(n_pipe < 0){
    12. printf("error: can not creat pipe!\n");
    13. perror("why");
    14. }
    15. int pid = fork();
    16. if(pid < 0){
    17. printf("error: creat child failed!\n");
    18. perror("why");
    19. }
    20. if(pid > 0){
    21. // sleep(2);
    22. printf("this is father pc\n");
    23. close(fd[0]);
    24. write(fd[1],"hello pipe from father;",strlen("hello pipe from father;"));
    25. close(fd[1]);
    26. }
    27. if(pid == 0){
    28. printf("this is child pc\n");
    29. close(fd[1]);
    30. read(fd[0],data1,128);
    31. printf("data : %s\n",data1);
    32. exit(9);
    33. }
    34. return 0;
    35. }

    打印: 

    mkfifo创建有名管道文件;成功返回0;失败返回-1并设置erron = -1;

    返回值判断报错值:EEXIST,可以锁定报错为文件已存在目录中;

    1. /*
    2. int mkfifo(const char *pathname, mode_t mode);
    3. RETURN VALUE
    4. On success mkfifo() and mkfifoat() return 0. In the case of
    5. an error, -1 is returned (in which case, errno is set appro‐
    6. priately).
    7. EEXIST pathname already exists. This includes the case where
    8. pathname is a symbolic link, dangling or not.
    9. */
    10. //例:
    11. #include
    12. #include
    13. #include
    14. #include
    15. int main()
    16. {
    17. if(mkfifo("./demo1.txt",0666) < 0 && errno == EEXIST ){
    18. printf("mkfifo error:\n");
    19. perror("why");
    20. }
    21. return 0;
    22. }

    mkfifo() 有名管道(会生成临时文件);  配合 open(); read(); write(); 实现进程间通讯;

    例 mkread +  mkwrite:

    1. //demo mkread:
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. int main()
    10. {
    11. char buf[30]={0};
    12. int nff = mkfifo("./demo10.txt",0600);
    13. if(nff < 0 || errno == EEXIST ){
    14. printf("mkfifo error:\n");
    15. perror("why");
    16. }
    17. if(nff == 0){
    18. printf("mkfifo OK! \n");
    19. }
    20. int fd = open("./demo10.txt",O_RDONLY);
    21. printf("open success\n");
    22. int n_read = read(fd,buf,30);
    23. printf("read %d byte frome fifo context:\n%s\n",n_read,buf);
    24. int n_sys = system("rm ./demo10.txt");
    25. if(n_sys < 0 || n_sys ==127 ){
    26. printf("./demo10.txt delect error! \n");
    27. perror("why");
    28. }else{
    29. printf("\n--------------------------------------------");
    30. printf("\nsystem: ./demo10.txt delect success !\n");
    31. printf("--------------------------------------------\n");
    32. }
    33. close(fd);
    34. return 0;
    35. }
    1. //demo mkwrite:
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. int main()
    9. {
    10. char buf[30]={"hello mkfifo file_read/write"};
    11. int fd = open("./demo10.txt",O_WRONLY);
    12. printf("open success\n");
    13. int n_write = write(fd,buf,strlen(buf));
    14. printf("write %d byte give fifo context:\n%s\n",n_write,buf);
    15. close(fd);
    16. return 0;
    17. }

    打印: 

  • 相关阅读:
    【Spring Cloud】新闻头条微服务项目:FreeMarker模板引擎实现文章静态页面生成
    线程方法join/join(timeout)源码分析
    树莓派和PC的串口通信编程
    倍市得CEM-ISV合作共创:体验加持,共建数字化产品护城河
    SpringBoot + SpringSecurity + redis 整合优化版(2)
    Spark on YARN 部署搭建详细图文教程
    Android使用Zxing库生成PDF417扫描后多一个字符A
    【JVM】JVM异常不打印堆栈信息 [ -XX:-OmitStackTraceInFastThrow ]
    java日志工具类
    docker 复习
  • 原文地址:https://blog.csdn.net/Wdf_123654/article/details/133994966