Linux下C对进程的操作


我将通过代码的方式说明一些进程的基本操作

获取当前进程的ID 和父进程ID
#include<stdio.h>                                                                              
#include<unistd.h> //包含我们进程相关的系统调用                                                
int main(int argc,char* *argv){                                                                
        pid_t my_pid,parent_pid; //pid_t是我们进程号的宏定义                                   
        my_pid = getpid();//getpid()获取当前进程的ID                                         
        parent_pid = getppid();//获取父进程ID                                                            
        printf("my_pid = %d\n",my_pid);                                                        
        printf("parent_pid = %d\n",parent_pid);                                                
        return 0;                                                                              
}

执行结果
在这里插入图片描述
我们还可以通过查看父进程看下我们的程序是哪一个进程创建的。调用命令ps -ef | grep 20524得到结果-bash啦
在这里插入图片描述

进程的创建

linux系统中创建进程采用fork系统调用,fork出来的进程除了pid其他的和父进程一样。为了区分父进程和子进程我们需要判断fork的返回值。失败返回-1,如果是父进程则返回子进程的ID,子进程就会返回0。如果没听明白的话。我们试想一下,父进程P与子进程C的程序是一样的,我们创建C肯定是为了执行不一样的任务。一样的代码如何执行不同的任务?所以就需要fork的返回值()来做分支判断。如果是0说明当前运行的是子进程C,就调用fork==0的分支,否则当前就是父进程在运行,就执行其他的。下面看代码:

#include<unistd.h>                                                                             
#include<sys/types.h>                                                                          
#include<stdio.h>                                                                              
#include<errno.h>                                                                              
int main(int argc,char* * argv){                                                               
        pid_t child;                                                                           
        printf("父进程ID = %d\n",getpid());                                                    
        child = fork();                                                                        
        if (child == -1){                                                                                
                printf("fork error\n");                                                        
        }else if(child == 0){                                                                  
                printf("子进程ID = %d\n",getpid());                                            
                sleep(5);                                                                      
                exit(0);                                                                       
        }else{                                                                                 
                sleep(10);                                                                     
                printf("parent again\n");                                                      
                exit(0);                                                                       
        }                                                                                      
}

执行结果
在这里插入图片描述
我们刚才说到了根据fork()返回值判断是子进程还是父进程,那么我们创建了子进程过后。如何执行不同的程序呢?可以使用exec族的系统调用,共有六个函数

  • int execl(const char *path, const char *arg, …);
  • int execlp(const char *file, const char *arg, …);
  • int execle(const char *path, const char *arg, …, char *const
    envp[]);
  • int execv(const char *path, char *const argv[]);
  • int execvp(const char *file, char *const argv[]);
  • int execve(const char *path, char *const argv[], char *const envp[]);

调用exec时进程被新的执行程序替代,然后从main开始执行,下面我们看一个例子:
创建test.c testexec.c文件,通过testexec.c中创建的子进程调用test的可执行文件,代码如下:

#test.c文件
#include<stdio.h>                                                                                        
#include<string.h>                                                                             
main(){                                                                                        
        int a,b,c;                                                                             
        int *p = NULL;                                                                         
                                                                                               
        a = 1;                                                                                 
        b =  2;                                                                                
        c = a+++b;                                                                             
        p = &c;                                                                                
        printf("*p = %d\n",*p);                                                                
}
#testexec.c文件
#include<unistd.h>                                                                             
#include<sys/types.h>                                                                          
#include<stdio.h>                                                                              
#include<errno.h>                                                                              
int main(int argc,char* * argv){                                                               
        pid_t child;                                                                           
        printf("父进程ID = %d\n",getpid());                                                    
        child = fork();                                                                        
        if (child == -1){                                                                      
                printf("fork error\n");                                                        
        }else if(child == 0){                                                                  
                printf("子进程ID = %d\n",getpid());                                            
                sleep(2);                                                                      
                execl("/root/gdbtest/exec/test",NULL);//执行同目录下的test文件                 
                printf("执行execl失败\n");//如果调用失败输出                                             
                exit(0);                                                                       
        }else{                                                                                 
                printf("parent again\n");                                                      
                exit(0);                                                                       
        }                                                                                      
}

从下图的执行结果我们可以看到成功的调用的test文件并且输出了3
在这里插入图片描述

进程间的通信

我们都知道进程间的通信包括管道、信号量、共享内存、消息队列、Socket的方式,但是我们可能都停留在理论的层面,所以用消息队列来做个实践。我们可以使用ipcs查看系统IPC
在这里插入图片描述
可以通过msgget()建立或者访问消息队列,通过msgsnd和msgrcv发送读取消息
通过一个例子说明,包括消息发送端和消息接受端

#发送端的程序,模拟消息队列的发送操作
#include<stdio.h>                                                                              
#include<stdlib.h>                                                                             
#include<unistd.h>                                                                             
#include<pthread.h>                                                                            
#include<fcntl.h>                                                                              
#include<sys/types.h>                                                                          
#include<sys/ipc.h>                                                                            
#include<sys/msg.h>                                                                            
#include<errno.h>                                                                              
struct my_msg{                                                                                 
  long int my_msg_type;                                                                        
  char text[BUFSIZ];                                                                           
 }                                                                                             
main(void){                                                                                    
        int running = 1;                                                                       
        int msgid;                                                                             
        struct my_msg msgbuf;                                                                  
        msgid = msgget((key_t)1234,0666|IPC_CREAT);                                                   
        if (msgid == -1){                                                                      
          printf("message error\n");                                                           
          exit(1);
          }                                                                                      
        while(running){                                                                        
                printf("enter some test:\n");                                                  
                fgets(msgbuf.text,BUFSIZ,stdin);                                               
                msgbuf.my_msg_type = 1;                                                        
                if(msgsnd(msgid,(void*)&msgbuf,BUFSIZ,0) == -1){                               
                        printf("msg send error\n");                                            
                        exit(1);                                                               
                }                                                                              
                if(strncmp(msgbuf.text,"end",3) == 0){                                         
                  running = 0;                                                                 
                }                                                                              
                                                                                               
        }                                                                                      
        exit(0);                                                                               
} 
#模拟消息的接受
#include<stdio.h>                                                                                     
#include<stdlib.h>                                                                             
#include<unistd.h>                                                                             
#include<pthread.h>                                                                            
#include<fcntl.h>                                                                              
#include<sys/types.h>                                                                          
#include<sys/ipc.h>                                                                            
#include<sys/msg.h>                                                                            
#include<errno.h>                                                                              
struct my_msg{                                                                                 
  long int my_msg_type;                                                                        
  char text[BUFSIZ];                                                                           
 }                                                                                             
main(void){                                                                                    
        int running = 1;                                                                       
        int msgid;                                                                             
        struct my_msg msgbuf;                                                                  
        long int msg_to_receive = 0;                                                           
        msgid = msgget((key_t)1234,0666|IPC_CREAT);                                            
        if (msgid == -1){                                                                      
          printf("message error\n");
          printf("message error\n");                                                           
          exit(1);                                                                             
        }                                                                                      
        while(running){                                                                        
                if(msgrcv(msgid,(void*)&msgbuf,BUFSIZ,msg_to_receive,0) == -1){                
                  printf("msg receive error\n");                                               
                  exit(1);                                                                     
                }                                                                              
                printf("%s\n",msgbuf.text);                                                    
                if(strncmp(msgbuf.text,"end",3) == 0){                                         
                  running = 0;                                                                 
                }                                                                              
        }                                                                                      
        if(msgctl(msgid,IPC_RMID,0) == -1)                                                     
        {                                                                                      
          printf("msg del error \n");                                                          
          exit(1);                                                                             
        }                                                                                      
        exit(0);                                                                               
}

最后我们运行程序看看效果
输入前:
在这里插入图片描述
在这里插入图片描述
输入后
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值