zoukankan      html  css  js  c++  java
  • linux下的C语言快速学习—进程和文件

    1、进程的概念

    这是操作系统课程里的一个概念 进程是一个开始执行但是还没有结束的程序的实例.就是可执行文件的具体实现. 一个程序可能有许多进程,而每一个进程又可以有许多子进程.依次循环下去,而产生子孙进程. 当程序被系统调用到内存以后,系统会给程序分配一定的资源(内存,设备等等)然后进行一系列的复杂操作,使程序变成进程以供系统调用.在系统里面只有进程没有程序,为了区分各个不同的进程,系统给每一个进程分配了一个ID(就象我们的身份证)以便识别. 为了充分的利用资源,系统还对进程区分了不同的状态.将进程分为新建,运行,阻塞,就绪和完成五个状态.
    下面是进程的程序

    #include <unistd.h>
    #include <sys/types.h>
    #include <stdio.h> 
    struct passwd { 
    char *pw_name; /* 登录名称 */ 
    char *pw_passwd; /* 登录口令 */ 
    uid_t pw_uid; /* 用户ID */ 
    gid_t pw_gid; /* 用户组ID */ 
    char *pw_gecos; /* 用户的真名 */ 
    char *pw_dir; /* 用户的目录 */ 
    char *pw_shell; /* 用户的SHELL */ 
    }; 
    struct passwd *getpwuid(uid_t uid);
    
    int main(int argc,char **argv) 
    { 
    pid_t my_pid,parent_pid; 
    uid_t my_uid,my_euid; 
    gid_t my_gid,my_egid; 
    struct passwd *my_info; 
    my_pid=getpid(); /* 获取本进程的序号 */ 
    parent_pid=getppid(); /*获取本进程父进程的编号*/
    my_uid=getuid(); 
    my_euid=geteuid(); 
    my_gid=getgid(); 
    my_egid=getegid(); 
    my_info=getpwuid(my_uid); 
    printf("Process ID:%ld\n",my_pid); 
    printf("Parent ID:%ld\n",parent_pid); 
    printf("User ID:%ld\n",my_uid); 
    printf("Effective User ID:%ld\n",my_euid); 
    printf("Group ID:%ld\n",my_gid); 
    printf("Effective Group ID: %ld\n",my_egid);
    if(my_info) 
    { 
    printf("My Login Name:%s\n" ,my_info->pw_name); 
    printf("My Password :%s\n" ,my_info->pw_passwd); 
    printf("My User ID :%ld\n",my_info->pw_uid); 
    printf("My Group ID :%ld\n",my_info->pw_gid); 
    printf("My Real Name:%s\n" ,my_info->pw_gecos); 
    printf("My Home Dir :%s\n", my_info->pw_dir); 
    printf("My Work Shell:%s\n", my_info->pw_shell); 
    }
    } 
    

    运行结果:

    Process ID:2390
    Parent ID:2100
    User ID:1000
    Effective User ID:1000
    Group ID:1000
    Effective Group ID: 1000
    My Login Name:jerry
    My Password :x
    My User ID :1000
    My Group ID :1000
    My Real Name:Administrator,,,
    My Home Dir :/home/jerry
    My Work Shell:/bin/bash

    关于创建创建进程(fork函数用法 )

    #include "sys/types.h"
    #include "unistd.h"
    #include "stdio.h"
    #include "stdlib.h"
    
    int main()
    {
      pid_t pid;
      char *message;
      int n;
      pid=fork();
      if(pid<0)
      {
        perror("fork failed");exit(1);
      }
      else if(pid==0)
      {
        message="This is the child\n";n=6;
      }
      else
      {
          message="This is the parent\n";n=3;
      }
      for(;n>0;n--)
      {
        printf(message);
        sleep(1);
      }
      return 0;
    }
    

    在父进程创建子进程(fork)以后,程序有两个进程,如果是父进程就会连续输出3次This is the parent,如果是子进程连续输出6次This is the child,但是在执行的时候不是这样的,执行结果如下;

    jerry@ubuntu:~/linux/jincheng1$ ./a.out
    This is the parent
    This is the child
    This is the parent
    This is the child
    This is the parent
    This is the child
    This is the child
    jerry@ubuntu:~/linux/jincheng1$ This is the child
    This is the child
    这是因为在循环输出是有这句代码sleep(1),在循环输出时会睡眠1秒,1秒是非常长的时间,子进程很有可能被调度到。同样地,子进程每打印一条消息就睡眠1秒,在这1秒期间父进程也很有可能被调度到。所以程序运行的结果基本上是父子进程交替打印。但这不是一定的,这取决与系统中其他进程的运行情况和内核调度算法。

    简单的IO重定向操作

    实现小写转化为大写的操作

    #include "ctype.h"
    #include "stdio.h"

    int main(void)
    {
      int ch;
      while((ch=getchar())!=EOF)
      {
        putchar(toupper(ch));
      }
      return 0;
    }

    编译以后

    使用shell进行进行重定向
    jerry@ubuntu:~/linux/jincheng1$ ./a.out < file.text
    HELLO WORD!

    2、文件操作

    文件复制简单实例

    #include <unistd.h> 
    #include <fcntl.h> 
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <errno.h> 
    #include <string.h> 
    #define BUFFER_SIZE 1024
    
    int main(int argc,char **argv)
    {
       int from_fd,to_fd;
       int bytes_read,bytes_write;
       char buffer[BUFFER_SIZE]; 
       char *ptr; 
       if(argc!=3) 
       { 
             fprintf(stderr,"Usage:%s fromfile tofile\n\a",argv[0]); 
             exit(1); 
       }
        /* 打开源文件 */ 
       if((from_fd=open(argv[1],O_RDONLY))==-1) 
       { 
              fprintf(stderr,"Open %s Error:%s\n",argv[1],strerror(errno)); 
              exit(1); 
        } 
         /* 创建目的文件 */ 
        if((to_fd=open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1) 
        { 
               fprintf(stderr,"Open %s Error:%s\n",argv[2],strerror(errno)); 
               exit(1); 
        }
        while(bytes_read=read(from_fd,buffer,BUFFER_SIZE))
        {
            /*当发生致命的操作时*/
            if((bytes_read==-1)&&(errno!=EINTR))break;
            else if(bytes_read>0)
            {
               ptr=buffer;
               while(bytes_write=write(to_fd,ptr,bytes_read))
               {
                  /*一个致命错误发生了*/
                  if((bytes_write==-1)&&(errno!=EINTR))break; 
                  else if(bytes_write==bytes_read) break; 
                  else if(bytes_write>0) 
                  {
                    ptr+=bytes_write;
                    bytes_read-=bytes_write;
                  }
               }
               if(bytes_write==-1)break; 
            }
        }
        close(from_fd); 
        close(to_fd); 
        exit(0);     
    }
    
  • 相关阅读:
    第21周六
    第21周五
    第21周四
    第21周三
    C/C++中各种类型int、long、double、char表示范围(最大最小值)
    插入排序
    面向对象的5个基本设计原则
    红黑树
    Cocos2d-x学习笔记(六) 定时器Schedule的简单应用
    SNMP协议具体解释
  • 原文地址:https://www.cnblogs.com/JerryWang1991/p/2189654.html
Copyright © 2011-2022 走看看