#include
#include //包含我们进程相关的系统调用
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
#include
#include
#include
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族的系统调用,共有六个函数
调用exec时进程被新的执行程序替代,然后从main开始执行,下面我们看一个例子:
创建test.c testexec.c文件,通过testexec.c中创建的子进程调用test的可执行文件,代码如下:
#test.c文件
#include
#include
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
#include
#include
#include
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
#include
#include
#include
#include
#include
#include
#include
#include
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
#include
#include
#include
#include
#include
#include
#include
#include
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);
}