首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在unix中使用fork()?为什么不用fork(pointerToFunctionToRun)形式的东西?

在Unix中,可以使用fork()系统调用来创建一个新的进程。fork()会复制当前进程的副本,并在新的进程中运行。下面是关于如何在Unix中使用fork()的完善答案:

  1. 使用fork()的步骤:
    • 在程序中调用fork()函数,它会返回一个整数值,表示新创建进程的ID。
    • 根据fork()的返回值,可以判断当前代码是在父进程还是子进程中执行。
    • 在父进程中,fork()返回新创建的子进程的ID,可以使用这个ID来跟踪子进程的状态或进行其他操作。
    • 在子进程中,fork()返回0,可以执行子进程需要完成的任务。
  2. 为什么不使用fork(pointerToFunctionToRun)形式的东西?
    • fork()是Unix系统提供的一个系统调用,用于创建新的进程。它是通过复制当前进程的副本来创建新进程的,因此不需要传递函数指针作为参数。
    • 使用fork(pointerToFunctionToRun)形式的东西,意味着需要在父进程中传递一个函数指针给子进程,这样子进程就可以执行指定的函数。但是这样做会引入更多的复杂性和风险,比如函数指针的有效性、内存管理等问题。
    • 另外,使用fork()可以更好地利用Unix系统的进程管理机制,使得进程的创建和管理更加简单和可靠。

总结:

在Unix中,使用fork()可以创建新的进程。它是通过复制当前进程的副本来创建新进程的,不需要传递函数指针作为参数。使用fork()的步骤包括调用fork()函数、根据返回值判断当前代码是在父进程还是子进程中执行,并在各自的进程中执行相应的任务。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Linux fork那些隐藏的开销

然而UNIX却不是整个世界! 似乎在对立的另一面,响荡着不同的声音,fork看起来是如此诡异,颠覆了初学者的认知,并且,fork开销巨大... 如果你知道fork开销巨大,那为何不用clone呢??...和上述create_process比较,fork简直就是一个丑陋的幽灵,不知道如此诡异的东西怎么在50年间被吹捧成了简单的典范,若不是UNIX卫道士们的鼓吹和灌输,fork应该是反面教材才对!...自1990年代起,《莱昂氏UNIX源码分析》中UNIX V6的代码就变成玩具了,其中很大的因素就是UNIX V6代码在1990年代成了一个 能跑但不能用的代码。...不能用的原因就在于当时的程序都已经很大了,很多古老的东西没有与时俱进,变得不再适用。 fork保留下来是个奇迹,其中多亏了写时复制的功劳。 写时复制无法继续拯救UNIX/Linux fork了。...事实上,早在1970年代,fork还未成为神话的年代,人们对创建新进程的方案持有大致两类观点,它们争议不断: 使用fork+exec。 使用spawn。 什么是spawn?

5K50

UnixLinux fork前传

一个流程图上的分支点分裂出来的分支显然是逻辑独立的,这便是可并行的前提,于是它们便可以表现为不同的 处理进程(process) 的形式,当时的表达还只是“process”这个术语,它还不是现代操作系统意义上的...关于这个设计思想为什么可以影响UNIX这么久,我想和Conway本人的“Conway’s law”不无关系,在这个law中,他提到:Any organization that designs a system...答案是根本不用产生新的进程,直接将命令程序的代码载入内存并 覆盖 掉shell进程的代码即可!...exec逻辑是shell程序的一部分,由于它会被所有的命令程序所使用,该逻辑也被封装到了exit调用中。...交换技术指的是用将进程的内存映像交换到磁盘,载入一个别的进程磁盘映像。 使用交换技术解决覆盖的问题,意味着要创建新的进程: 在新的进程中执行命令程序。

74620
  • UnixLinux fork前传

    关于这个设计思想为什么可以影响UNIX这么久,我想和Conway本人的“Conway’s law”不无关系,在这个law中,他提到: Any organization that designs a system...答案是根本不用产生新的进程,直接将命令程序的代码载入内存并 覆盖 掉shell进程的代码即可!...exec逻辑是shell程序的一部分,由于它会被所有的命令程序所使用,该逻辑也被封装到了exit调用中。...交换技术指的是用将进程的内存映像交换到磁盘,载入一个别的进程磁盘映像。 使用交换技术解决覆盖的问题,意味着要创建新的进程: 在新的进程中执行命令程序。...换句话说,UNIX只是借用了fork的copy逻辑的实现,来完成一件别的事。 于是,UNIX非常粗暴的实现了fork!即完全copy父进程,这就是直到现在我们依然在使用的fork系统调用: ?

    91132

    UNIX(进程间通信):01---Linux进程通信方式

    事实上,很多Unix版本的单机IPC留有BSD的痕迹,如4.4BSD支持的匿名内存映射、4.3+BSD对可靠信号语义的实现等等。...图一给出了linux 所支持的各种IPC手段,在本文接下来的讨论中,为了避免概念上的混淆,在尽可能少提及Unix的各个版本的情况下,所有问题的讨论最终都会归结到Linux环境下的进程间通信上来。...共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。...fork都是由do_fork实现的,do_fork的简化流程如下图: ? fork函数 ? fork函数时调用一次,返回两次。在父进程和子进程中各调用一次。...可以发现子进程和父进程之间并没有对各自的变量产生影响。 一般来说,fork之后父、子进程执行顺序是不确定的,这取决于内核调度算法。进程之间实现同步需要进行进程通信。 什么时候使用fork呢?

    2.7K30

    一道FORK的面试

    作者:陈皓 出处:https://coolshell.cn/articles/7965.html 前两天有人问了个关于Unix的fork()系统调用的面试题,这个题正好是我大约十年前找工作时某公司问我的一个题...要讲清这个题,我们首先需要知道fork()系统调用的特性, fork()系统调用是Unix下以自身进程创建子进程的系统调用,一次调用,两次返回,如果返回是0,则是子进程,如果返回值>0,则是父进程(返回值是子进程的...还有一个很重要的东西是,在fork()的调用处,整个父进程空间会原模原样地复制到子进程中,包括指令,变量值,程序调用栈,环境变量,缓冲区,等等。...所以,上面的那个程序为什么会输入8个“-”,这是因为printf(“-“);语句有buffer,所以,对于上述程序,printf(“-“);把“-”放到了缓存中,并没有真正的输出(参看《C语言的迷题》中的第一题...另外,多说一下,我们知道,Unix下的设备有“块设备”和“字符设备”的概念,所谓块设备,就是以一块一块的数据存取的设备,字符设备是一次存取一个字符的设备。磁盘、内存都是块设备,字符设备如键盘和串口。

    72010

    当你在 Linux 上启动一个进程时会发生什么?

    英文:Julia Evans,编译:Linux中国 / jessie-pang linux.cn/article-9256-1.html 本文是关于 fork 和 exec 是如何在 Unix 上工作的...fork 和 exec Linux 上的 posix_spawn 是通过两个系统调用实现的,分别是 fork 和 exec(实际上是 execve),这些都是人们常常使用的。...尽管在 OS X 上,人们使用 posix_spawn,而 fork 和 exec 是不提倡的,但我们将讨论的是 Linux。 Linux 中的每个进程都存在于“进程树”中。...这就是 fork 和 exec 在程序中的实现。我写了一段 C 的伪代码。请记住,fork 也可能会失败哦。 intpid=fork(); // 我要分身啦 // “我”是谁呢?...并让另一个程序吃掉你的脑子的时候,实际上几乎所有东西都是相同的!

    1.1K70

    2013年 腾讯笔试题:fork()

    要讲清这个题,我们首先需要知道fork()系统调用的特性, fork()系统调用是Unix下以自身进程创建子进程的系统调用,一次调用,两次返回,如果返回是0,则是子进程,如果返回值>0,则是父进程(返回值是子进程的...还有一个很重要的东西是,在fork()的调用处,整个父进程空间会原模原样地复制到子进程中,包括指令,变量值,程序调用栈,环境变量,缓冲区,等等。...所以,上面的那个程序为什么会输入8个“-”,这是因为printf(“-”);语句有buffer,所以,对于上述程序,printf(“-”);把“-”放到了缓存中,并没有真正的输出,在fork的时候,缓存被复制到了子进程空间...另外,多说一下,我们知道,Unix下的设备有“块设备”和“字符设备”的概念,所谓块设备,就是以一块一块的数据存取的设备,字符设备是一次存取一个字符的设备。磁盘、内存都是块设备,字符设备如键盘和串口。...需要注意的是,标准输出是行缓冲,所以遇到“\n”的时候会刷出缓冲区,但对于磁盘这个块设备来说,“\n”并不会引起缓冲区刷出的动作,那是全缓冲,你可以使用setvbuf来设置缓冲区大小,或是用fflush

    44210

    linux内核中听过就能记住的概念

    所以换了台好点的机器就没有这个问题了。但是句柄超限到底是个什么东西呢?先来看看linux内核的一些基本概念。   大局观嘛,先来看看unix的体系结构。 ?    ...刚才说的匿名管道和命名管道都算一种。除此之外,还有:信号,消息队列,共享内存,信号量和套接字。不用头疼,看到最后你很可能会有豁然开朗的感觉,学的东西终于可以串在一起了。   ...读写文件也需要使用文件描述符来指定待读写的文件。文件描述符形式上是非负整数,实际上它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。...在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符往往值适用于unix,linux这样的操作系统。习惯上,标准输入的文件描述符是0,标准输出是1,标准错误是2....打开文件(open files)包括文件句柄但不仅限于文件句柄,由于lnux所有的事务都以文件的形式存在,要使用诸如共享内存,信号量,消息队列,内存映射等都会打开文件,但这些不会占用文件句柄。

    74620

    POSIX 螺纹具体解释(1-概要)

    那么为什么对于大多数合作性任务。多线程比多个独立的进程更优越呢?这是由于,线程共享同样的内存空间。 不同的线程能够存取内存中的同一个变量。所以,程序中的全部线程都能够读或写声明过的全局变量。...假设曾用 fork() 编写过重要代码。就会认识到这个工具的重要性。为什么呢?尽管 fork() 同意创建多个进程,但它还会带来下面通信问题: 怎样让多个进程相互通信。...管道,信号量或共享内存) UNIX PROCESS THREADS WITHIN A UNIX PROCESS 线程使用并存在于进程资源中,还能够被操作系统调用并独立地执行,这主要是由于线程只复制必要的资源以使自己得以存在并执行...因此,在UNIX环境下线程: 存在于进程,使用进程资源 拥有自己独立的控制流。...由于大部分额外开销已经在进程创建时完毕了 由于在同一个进程中的线程共享资源: 一个线程对系统资源(如关闭一个文件)的改变对全部其他线程是能够见的 两个相同值的指针指向相同的数据 读写同一个内存位置是可能的

    27130

    Linux 中的 Process Group 和 Session

    看了一些讲进程控制的书和文章, 感觉都比较老了, 不少都还在讲 double fork 的原理及意义, 而现实是 systemd 已经接管了几乎整个 Linux 世界, double fork 这种东西真的不应该存在了..., 至少在新的程序中不应该再使用了, 所以有了这篇文章....进程可以理解为 "进行中的程序", 在 Linux 上可以通过 fork 来创建新的进程, 然后可以使用 exec 来在子进程或者父进程中执行新的程序....答案是: shell 会向session的所有进程组发送 SIGHUP 信号, 所以运行中的后台进程组也会退出. daemonize 在 Unix 的上古时期, 没有 Process Manager 这个概念..., 所以每个守护进程(比如说 apache)都需要自己变成守护进程, 一般来说是通过 double fork 的形式: fork 第一次, 确保自己不是 group leader setsid, 创建新的

    1.8K30

    redis的持久化存储RDB的原理分析

    我们看看RDB的使用:RDB 功能最核心的是 rdbSave 和 rdbLoad 两个函数, 前者用于生成 RDB 文件到磁盘, 而后者则用于将 RDB 文件中的数据重新载入到内存中: ?...这几句是他redis为什么用子进程而不用子线程的原因之一,一个进程他可以包含多个线程,这多个线程是使用的这个进程分配下来的内存地址进行工作的。...*在计算机编程领域,尤其是 Unix 和类 Unix 系统中,fork 都是一个进程用于创建自己拷贝的操作,它往往都是被操作系统内核实现的系统调用,也是操作系统在 nix 系统中创建新进程的主要方法。...总结 我们通过上面的分析,RDB是redis定时持久化的一个业务逻辑,可以通过命令SAVA 和 BGSAVE 进行同步持久化,使用BGSAVA不会影响到客户端的使用。而使用SAVA会影响客户端的使用。...BGSAVE的实现是通过调用fork()和 rdbsave实现的,其中fork()的意思就是创建一个子进程,且采用的是写时拷贝。 为什么通过子进程来解决这个问题呢?

    69120

    Linux-Copy On Write写时复制机制初探

    ---- *Unix 在传统的Unix环境下,有两个基本的操作用于创建和修改进程: 函数fork( )用来创建一个新的进程,该进程几乎是当前进程的一个完全拷贝 函数族exec( )用来启动另外的进程以取代当前运行的进程...故: 父进程在执行if代码块的时候,fpid变量的值是子进程的pid,子进程在执行if代码块的时候,fpid变量的值是0 ---- 函数族exec( ) 在Linux中要使用exec函数族。...---- 为什么有了COW? 早期的 Unix 在实现 fork 系统调用时,并没有使用该技术,创建新进程的开销很大。...出于效率考虑,Copy On Write 技术引入到进程中,fork 之后的父进程和子进程完全共享数据段、代码段、堆和栈等的完全副本。...如果子进程不对内存空间进行写入操作的话,内存空间中的数据并不会复制给子进程,这样创建子进程的速度就很快 ,因为不用复制,直接引用父进程的物理空间 ,并且如果在fork函数返回之后,子进程第一时间exec

    3.6K10

    Swoole 学习:协程、线程、IO多路复用、PHP多进程。

    ,但只有一点不同,如果fork成功,子进程中fork的返回值是0, 父进程中fork的返回值是子进程的进程号,如果fork失败,父进程会返回错误。...可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,他们分别作不同的工作,也就是分岔了,这也是fork为什么叫fork的原因。...共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。...套接字通信 第三方通信,使用文件操作,mysql,redis等方法也可实现通信 2.进程信号  信号(Signals )是Unix系统中使用的最古老的进程间通信的方法之一。...信号是在Unix System V中首先引入的,它实现了15种信号,但很不可靠。BSD4.2解决了其中的许多问题,而在BSD4.3中进一步加强和改善了信号机制。但两者的接口不完全兼容。

    66360

    UNPv1第二十三章:线程

    在传统的UNIX模型中,当一个进程需要由另一个实体执行某件事时,该进程派生(fork)一个子进程,让子进程去进行处理。...UNIX下的大多数网络服务器程序都是这么编写的,这在我们的并发服务程序例子中可以看出:父进程接收连接,派生子进程,子进程处理与客户的交互。...虽然这种模式很多年来使用的很好,但是fork有一些问题: fork是昂贵的。内存映像要从父进程拷贝到子进程,所有描述字要在子进程中复制等等。...目前的实现使用一种称做写时拷贝(copy-on-write)技术,可避免父进程数据空间向子进程的拷贝,除非子进程需要自己的拷贝。尽管有这种优化技术,fork仍然是昂贵的。...在通常的Unix编程中,我们没有遇到这种并发编程问题,因为用fork时,除了描述字外,父进程和子进程不共享任何东西。但是,当我们讨论进程间的共享内存时仍将遇到这类问题。

    47820

    买了很多书,看了很多教程,仍然看不懂开源代码......

    在各类知识付费课程中,有一类课程是介绍业界或者大家平常工作中用到的一些开源软件的原理的,进一步说,有的是分析这类软件的源码的,如 Nginx、Netty、Spring Boot。...为什么建议以阅读相关源码为主,而不是其他相关教程呢?...,也就是说,你学习的这些东西其实不是第一手的,而是经过别人加工或者理解意译过的,在这个过程中如果别人理解有偏差,那么你或多或少的会受一点影响。...,到启动 gdb 调试再到使用 gdb 中断 Redis 查看各种状态,循序渐进地介绍各种 gdb 调试命令; 介绍了实际工作中 gdb 的各种高级调试技巧,例如如何显示超长字符串、如何使用 gdb 调试多进程程序等等...# fork之后gdb attach到子进程 set follow-fork child # fork之后gdb attach到父进程,这是默认值 set follow-fork parent 我们可以使用

    1.1K22

    Rust FFI 编程 - libc crate

    因此,你可以使用 libc::foo 这种形式访问这个库中的任何导出内容。 它可以与 std 配合使用,也可以在 no_std 环境下使用。...这一套东西可不得了,它是计算机工程历史这么多年积累下来的成体系的精华之作。这套精华的体系就叫作Unix环境编程。这套体系在《UNIX环境高级编程(第3版)》这本书中做了权威讲解。...而 libc 可以对进程的操作(及后面对子进程的功能扩充,父进程中的信号管理等),做到完全的控制,更加灵活,功能强大; std 本身无法实现进程 fork 的功能。...应该说,使用 libc,类 Unix 平台上的所有系统编程,之前只能由 C 完成的工作,现在都能用 Rust 来做了。在这一层面上,C 能做到的事情,Rust 都能做到。...而 libc 中,对这些内容,也重新定义了一份(比如:https://docs.rs/libc/0.2.69/libc/type.c_char.html)。为什么呢?

    3.1K21

    MIT 6.S081 (BOOK-RISCV-REV1)教材第一章内容 --- 操作系统接口

    (Unix的命令行用户界面)如何使用它们的讨论来阐释。...你或许想知道为什么exec和fork没有组合成为一个系统调用,稍后我们将会看到shell在其I/O重定向的实现中利用了这种分离。...为了避免创建一个重复的进程然后立即替换它(使用exec)的浪费,操作内核通过使用虚拟内存技术(如copy-on-write)优化 fork 。...新分配的文件描述符总是当前进程中编号最小的未使用描述符。 文件描述符和fork相互作用,使I/O重定向更容易实现。...Unix以用户级程序的形式提供了可从shell调用的文件实用程序,例如mkdir、ln和rm。这种设计允许任何人通过添加新的用户级程序来扩展命令行接口。

    30621

    60秒问答:请问下面的程序一共输出多少个hello,world”

    ()系统调用是Unix下以自身进程创建子进程的系统调用,一次调用,两次返回,如果返回是0,则是子进程,如果返回值>0,则是父进程(返回值是子进程的pid),这是众为周知的。...【青铜:都知道】 还有一个很重要的东西是,在fork()的调用处,整个父进程空间会原模原样地复制到子进程中,包括指令,变量值,程序调用栈,环境变量,缓冲区,等等。【白银:别人知道我不知道】 2....关于缓冲区,Unix下的设备块设备和字符设备的概念, 所谓块设备,就是以一块一块的数据存取的设备,字符设备是一次存取一个字符的设备。磁盘、内存都是块设备,字符设备如键盘和串口。...需要注意的是,标准输出是行缓冲,所以遇到“\n”的时候会刷出缓冲区, 但对于磁盘这个块设备来说,“\n”并不会引起缓冲区刷出的动作,那是全缓冲,你可以使用setvbuf来设置缓冲区大小,或是用fflush...(如键盘,直接相应中断) 这是因为printf(“-”);语句有buffer,所以,对于上述程序,printf(“-”);把“-”放到了缓存中, 在fork的时候,缓存被复制到了子进程空间,所以,就多了两个

    1.5K40

    【翻译】XV6-DRAFT as of September 3,2014 第0章 操作系统接口

    这些系统调用在shell上的使用,体现了它们的设计是多么独具匠心。 shell是一个普通的程序,它读取用户的命令并且执行它们,shell也是传统的类Unix(Unix-like)系统中主要的用户界面。...在父进程的程序中,fork函数返回的是子进程的pid,而在子进程的程序中,fork函数返回0。...你或许会疑惑为什么fork与exec不合并为一个系统调用,我们稍后将看到,把创建进程与加载进程分割成两个系统调用是一个灵巧的设计。...现在你应该很清楚为什么把fork与exec分开调用是个好主意了:这种分离使得shell可以在子进程执行指定程序之前对子进程进行修改。...这种想法引发了“软件工具”的文化以及Unix的强大,而shell也成为首个所谓的“脚本语言”。Unix的系统调用接口在今天仍然存在于许多操作系统上,如BSD、Linux以及Mac OS X。

    60560

    Node.js 多进程(上)

    Node 提供了 child_process 模块来创建子进程,方法有: exec - child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回...fork - child_process.fork 是 spawn()的特殊形式,用于在子进程中运行的模块,如 fork('./son.js') 相当于 spawn('node', ['....与spawn方法不同的是,fork会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。...---- exec() 方法 child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。...默认: 在 UNIX 中为/bin/sh, 在 Windows 中为cmd.exe, Shell 应当能识别 -c开关在 UNIX 中,或 /s /c 在 Windows 中。

    67820
    领券