目前我正在学习fork(),并execv()和我有关于组合的效率问题.
我看到了以下标准代码:
pid = fork();
if(pid < 0){
//handle fork error
}
else if (pid == 0){
execv("son_prog", argv_son);
//do father code
Run Code Online (Sandbox Code Playgroud)
我知道fork()克隆整个过程(复制整个堆等)并execv()用新程序替换当前地址空间.考虑到这一点,使用这种组合不是非常低效吗?我们正在复制进程的整个地址空间,然后立即覆盖它.
所以我的问题是:
即使我们有浪费,使用这个组合(而不是其他解决方案)使人们仍然使用它的优势是什么?
我试图通过Mac上的终端运行一个java程序,但得到:
Error: Could not find or load main class (MY CLASSNAME)
Run Code Online (Sandbox Code Playgroud)
我用Eclipse编译了这个应用程序,当我用Eclipse运行它时,它工作正常.此外,我在正确的目录中,因为当我在终端中键入"ls"时,它列出了所有文件,包括我试图运行的类文件.
这是我输入的内容:
java mainClass
Run Code Online (Sandbox Code Playgroud)
我非常感谢帮助解决这个问题!
谢谢,
院长
编辑:解决方案 - 而不是java mainClass,它也必须有包:java startPackage.mainClass
当引用目标文件/可执行文件时,我对“段”和“节”之间是否存在差异感到困惑。
根据https://en.wikipedia.org/wiki/Object_file:
大多数目标文件格式被构造为单独的数据部分,每个部分包含某种类型的数据。
不过,本文稍后会继续讨论段(例如代码段、数据段等)。
此外,PE 文件格式(Windows 中的 .exe/.dll/.coff)将这些不同部分称为节(https://msdn.microsoft.com/en-us/library/windows/desktop/ms680547(v= vs.85).aspx )。
所以我的问题是:两者之间有区别还是实际上是同义词?
我正在运行以下代码,我在Mac上用c编写.
#include <unistd.h>
#include <stdio.h>
int main(int argc, const char * argv[]) {
int i = 0;
printf("Starting pid:%d\n", getpid());
while(i++<3){
int ret = fork();
printf("hello(%d)%d, %d ", i, getpid(), ret);
if(!ret){
printf("\n");
return 0;}
}
}
Run Code Online (Sandbox Code Playgroud)
我想到的目标是共有6张照片 - 其中3张来自原始父母(pid印在"Starting pid"中),还有1张来自3个衍生儿童.相反,我收到的是:
Starting pid:7998
hello(1)8009, 0
hello(1)7998, 8009 hello(2)8010, 0
hello(1)7998, 8009 hello(2)7998, 8010 hello(3)7998, 8011 hello(1)7998, 8009 hello(2)7998, 8010 hello(3)8011, 0
Run Code Online (Sandbox Code Playgroud)
请注意,原始父级(7998)打印6次(当i == 1时为三次,i == 2时为两次,i == 3时为一次).
为什么会这样?为什么我没有从父母那里收到3份照片(一次当i == 1,i == 2,i == 3).如果我们从父母的角度来看它 - 有一个while循环,我们应该只打3次内部的print语句.
是叉子是异步还是什么?我错过了什么?
今天,在课堂上,我们研究了Linux中的等待队列,并在谈论独占/非独占等待时出现了一些有趣的事情。
提出了一个问题: 如果等待队列中有一些进程处于排他状态,而另一些处于非排他状态,将会发生什么情况。
讲师回答说,wake_up()它将遍历队列,唤醒所有非独占进程,直到遇到独占进程,然后它将唤醒最后一个进程并停止。
例如: 令N,E分别代表等待队列中的非排他性和排他性过程:
N - N - N - E - N - E - N - N
Run Code Online (Sandbox Code Playgroud)
讲师声称前四个等待将被唤醒(NNNE),并且内核将在第一个E之后停止遍历。
这听起来很奇怪,因为E是排他性的,这意味着它不希望与其他任何人一起被唤醒,在这种情况下,它与其他人一起被唤醒。
搜索该问题得出以下结果:
当“唤醒”等待队列时,将为调度程序启用等待队列上的所有任务。如果使用排他功能将任务添加到等待队列中,则唤醒调用将仅唤醒一个排他任务,而其他任务仍在等待。如果将排他任务和非排他任务的混合添加到队列中,则唤醒功能将唤醒所有非排他任务,直到它唤醒排他任务。唤醒顺序通常与将任务添加到队列的顺序相反。 https://blackfin.uclinux.org/doku.php?id=linux-kernel:wait_queues
哪一个是正确的?真正的答案是否完全不同?
注意:在课堂上我们谈论的是Linux2.4.18-14,i386(如果系统上需要其他信息,请发表评论)