Linux使用fork()方法创建进程

简介: Linux使用fork()方法创建进程

在做操作系统的实验过程中,自己安装了Ubuntu(18.04.1)64位,在这里给大家安利一个VX公众号:软件安装管家。这里真的有好多好多的软件,非常全面并且安装教程非常详细,强烈推荐!!!


在此声明,我所有代码都是基于Ubuntu(18.04.1)64位,使用vim编辑器编辑,gcc编译的。兼容性不知道如何。因为自己也是linux新人,难免有一些不太准确的地方,还希望和兄弟们交流学习。


实验应该是要验证进程之间的并发性,就是输出字符的顺序是不一定的,但是也许是由于代码太简单的缘故,导致输出顺序每次都是固定的。。很是尴尬

#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
int main()
{
        pid_t pid1,pid2;
        pid1 = fork();//创建一个新process
        if(pid1 < 0)
        {
                printf("创建进程失败!");
                exit(1);
        }
        else if(pid1 == 0)
        {
               printf("b");
        }
        else
        {
                pid2 = fork();//创建第二个新进程
                if(pid2 < 0)
                {
                        printf("进程创建失败!");
                        exit(1);
                }
                else if(pid2 == 0)
                {
                        printf("c");
                }
                else
              {
                        printf("a");
                }
        }
        //getchar();//如果运行错行,再放开此句,拦住父进程,不让其结束
        return 0;
}

更尴尬的是,这个代码的运行结果:

image.png


a居然打印在了那个地方???小弟刚开始接触linux,人都傻了,这是因为主进程直接结束,它运行速度甚至快于终端输出??


我试着在代码尾部加了getchar()拦截一下主进程:

image.png

这下输出就舒服多了。。。但是我运行了很多遍,顺序都是这样,所以就改成for循环来打印,在每个进程执行过程中,用for循环打印数据。

#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
int main()
{
        pid_t pid1,pid2;
        pid1 = fork();//创建一个新process
        if(pid1 < 0)
        {
                printf("创建进程失败!");
                exit(1);
        }
        else if(pid1 == 0)
        {
        for(int i = 0;i<1000;i++)
      {
        printf("b  子进程1的标识符是%d",getpid());
      }              
        }
        else
        {
                pid2 = fork();//创建第二个新进程
                if(pid2 < 0)
                {
                        printf("进程创建失败!");
                        exit(1);
                }
                else if(pid2 == 0)
                {
          for(int i = 0;i<1000;i++)
          {
            printf("c  子进程2的标识符是%d",getpid());
          }
          }   
          else
        {
          for(int i = 0;i<1000;i++)
          {
            printf("a  父进程的标识符是%d",getpid());
          } 
            } 
        }
        getchar();//为了拦住进程,不让进程结束
        return 0;
}

运行结果:

image.png

交叉打印,感觉有那味了,并发执行。

接下来又要求给进程上锁,使用lockf()函数,这个原理基本就和Windows的临界区是一个概念,申请到锁的资源才可以执行,并且在释放资源之前,不会被其他进程抢占这个资源,实现了进程间同步机制。


附上代码以及截图:

#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
int main()
{
        pid_t pid1,pid2;
        pid1 = fork();//创建一个新process
        if(pid1 < 0)
        {
                printf("创建进程失败!");
                exit(1);
        }
        else if(pid1 == 0)
        {
                lockf(1,1,0);//上锁
                for(int i = 0;i<100;i++)
                {
                        printf("Chile_1  子进程1标识是%d\r\n",getpid());
                }
                lockf(1,0,0);//解锁
        }
        else
        {
                pid2 = fork();//创建第二个新进程
                if(pid2 < 0)
                {
                        printf("进程创建失败!");
                        exit(1);
                }
                else if(pid2 == 0)
                {
                        lockf(1,1,0);//上锁
                        for(int i = 0;i<100;i++)
                        {
                                printf("Child_2  子进程2标识是%d\r\n",getpid());
                        }
                        lockf(1,0,0);//解锁
                }
                else
                {
                        lockf(1,1,0);//上锁
                        for(int i = 0;i<100;i++)
                        {
                                printf("FatherProcess 父进程标识是%d\r\n",getpid());
                        }
                        lockf(1,0,0);//解锁
                }
        }
        getchar();//为了拦住进程,不让进程结束
        getchar();
        return 0;
}

image.png


image.png


image.png


目录
相关文章
|
4月前
|
Ubuntu 物联网 Linux
从零安装一个Linux操作系统几种方法,以Ubuntu18.04为例
一切就绪后,我们就可以安装操作系统了。当系统通过优盘引导起来之后,我们就可以看到跟虚拟机中一样的安装向导了。之后,大家按照虚拟机中的顺序安装即可。 好了,今天主要介绍了Ubuntu Server版操作系统的安装过程,关于如何使用该操作系统,及操作系统更深层的原理,还请关注本号及相关圈子。
|
4月前
|
缓存 监控 Linux
Linux系统清理缓存(buff/cache)的有效方法。
总结而言,在大多数情形下你不必担心Linux中buffer与cache占用过多内存在影响到其他程序运行;因为当程序请求更多内存在没有足够可用资源时,Linux会自行调整其占有量。只有当你明确知道当前环境与需求并希望立即回收这部分资源给即将运行重负载任务之前才考虑上述方法去主动干预。
1625 10
|
4月前
|
Ubuntu Linux 图形学
推广与体验Ubuntu Linux的便捷方法
如果你的朋友或家人对尝试Linux感兴趣,但希望在安装之前先体验一下,你可以分享以下链接给他们:Ubuntu在线导览。通过这个链接,他们可以在任何地方轻松体验Ubuntu,无需安装即可深入了解这个流行的操作系统。
|
4月前
|
XML 缓存 Linux
在Linux环境下解决Visual Studio Code字体显示异常和字体替换方法。
解决Linux下VS Code字体显示异常,需要对Linux字体渲染机制有所理解,并对VS Code的配置选项进行合理设置。替换字体时则要通过系统字体配置或VS Code设置来完成。通过上述方法,可以有效地解决字体显示问题,从而提升代码编辑的视觉体验。
572 0
|
7月前
|
NoSQL Linux 编译器
GDB符号表概念和在Linux下获取符号表的方法
通过掌握这些关于GDB符号表的知识,你可以更好地管理和理解你的程序,希望这些知识可以帮助你更有效地进行调试工作。
333 16
|
7月前
|
Web App开发 Linux 程序员
获取和理解Linux进程以及其PID的基础知识。
总的来说,理解Linux进程及其PID需要我们明白,进程就如同汽车,负责执行任务,而PID则是独特的车牌号,为我们提供了管理的便利。知道这个,我们就可以更好地理解和操作Linux系统,甚至通过对进程的有效管理,让系统运行得更加顺畅。
215 16
|
5月前
|
网络协议 Ubuntu Linux
Wireguard in Linux的安装方法
本文介绍了如何在Ubuntu和Rocky Linux中安装配置WireGuard,并探讨了配置过程中可能出现的DNS泄露问题及解决方法,包括通过nmtui设置DNS及调整DNS优先级参数。
|
6月前
|
监控 Shell Linux
Linux进程控制(详细讲解)
进程等待是系统通过调用特定的接口(如waitwaitpid)来实现的。来进行对子进程状态检测与回收的功能。
131 0
|
6月前
|
存储 负载均衡 算法
Linux2.6内核进程调度队列
本篇文章是Linux进程系列中的最后一篇文章,本来是想放在上一篇文章的结尾的,但是想了想还是单独写一篇文章吧,虽然说这部分内容是比较难的,所有一般来说是简单的提及带过的,但是为了让大家对进程有更深的理解与认识,还是看了一些别人的文章,然后学习了学习,然后对此做了总结,尽可能详细的介绍明白。最后推荐一篇文章Linux的进程优先级 NI 和 PR - 简书。
200 0