导航:首页 > 源码编译 > 父子进程编译怎么实现

父子进程编译怎么实现

发布时间:2022-06-22 18:07:32

A. 关于父子进程的执行顺序和执行过程

(1)fork
函数用于从已存在进程中创建一个新进程。新进程称为子进程,而原进程称为父进

程。这两个分别带回它们各自的返回值,其中父进程的返回值是子进程的进程号,而子进程

则返回
0,大于0则是父进程。因此,可以通过返回值来判定该进程是父进程还是子进程。

使用 fork
函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地

址空间,包括进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设定、进程

优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等,而子进程所独有的只

有它的进程号、资源使用和计时器等。因此可以看出,使用
fork
函数的代价是很大的,它复

制了父进程中的代码段、数据段和堆栈段里的大部分内容,使得
fork
函数的执行速度并不

很快。
(2)所以他们是同时进行的,要想停止父进程或子进程 就用exit()函数退出创建子进程,父进程退出

pid=fork();

if(pid>0){

exit(0);
}

(3)如果不想退出就用wait
函数,它是用于使父进程(也就是调用
wait
的进程)阻塞,直到一个子进程结束或者该进程接到了一个指定的信号为止。如果该父进程没有子进程或者他的子进程已经结束,
wait则就会立即返回。waitpid
的作用和 wait
一样,但它并不一定要等待第一个终止的子进程,它还有若干选项,如可提供一个非阻塞版本的
wait
功能,也能支持作业控制。实际上
wait
函数只waitpid
函数的一个特例,在
linux 内部实现
wait
函数时直接调用的就是 waitpid
函数。它们的头文件都是#include
<sys/types.h> #include <sys/wait.h>

B. linux 父进程创建子进程的例子

父进程为什么要创建子进程呢?前面我们已经说过了Linux是一个多用户操作系统,在同一时间会有许多的用户在争夺系统的资源.有时进程为了早一点完成任务就创建子进程来争夺资源. 一旦子进程被创建,父子进程一起从fork处继续执行,相互竞争系统的资源.有时候我们希望子进程继续执行,而父进程阻塞直到子进程完成任务.这个时候我们可以调用wait或者waitpid系统调用.
#i nclude
#i nclude

pid_t wait(int *stat_loc);
pid_t waitpid(pid_t pid,int *stat_loc,int options);

wait系统调用会使父进程阻塞直到一个子进程结束或者是父进程接受到了一个信号.如果没有父进程没有子进程或者他的子进程已经结束了wait回立即返回.成功时(因一个子进程结束)wait将返回子进程的ID,否则返回-1,并设置全局变量errno.stat_loc是子进程的退出状态.子进程调用exit,_exit 或者是return来设置这个值. 为了得到这个值Linux定义了几个宏来测试这个返回值.
WIFEXITED:判断子进程退出值是非0
WEXITSTATUS:判断子进程的退出值(当子进程退出时非0).
WIFSIGNALED:子进程由于有没有获得的信号而退出.
WTERMSIG:子进程没有获得的信号号(在WIFSIGNALED为真时才有意义).
waitpid等待指定的子进程直到子进程返回.如果pid为正值则等待指定的进程(pid).如果为0则等待任何一个组ID和调用者的组ID相同的进程.为-1时等同于wait调用.小于-1时等待任何一个组ID等于pid绝对值的进程. stat_loc和wait的意义一样. options可以决定父进程的状态.可以取两个值 WNOHANG:父进程立即返回当没有子进程存在时. WUNTACHED:当子进程结束时waitpid返回,但是子进程的退出状态不可得到.
父进程创建子进程后,子进程一般要执行不同的程序.为了调用系统程序,我们可以使用系统调用exec族调用.exec族调用有着5个函数.
#i nclude

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

exec族调用可以执行给定程序.关于exec族调用的详细解说可以参考系统手册(man execl). 下面我们来学习一个实例.注意编译的时候要加 -lm以便连接数学函数库.

#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude

void main(void)
{
pid_t child;
int status;

printf(”This will demostrate how to get child status\n”);
if((child=fork())==-1)
{
printf(”Fork Error :%s\n”,strerror(errno));
exit(1);
}
else if(child==0)
{
int i;
printf(”I am the child:%ld\n”,getpid());
for(i=0;i<1000000;i++) sin(i);
i=5;
printf(”I exit with %d\n”,i);
exit(i);
}
while(((child=wait(&status))==-1)&(errno==EINTR));
if(child==-1)
printf(”Wait Error:%s\n”,strerror(errno));
else if(!status)
printf(”Child %ld terminated normally return status is zero\n”,
child);
else if(WIFEXITED(status))
printf(”Child %ld terminated normally return status is %d\n”,
child,WEXITSTATUS(status));
else if(WIFSIGNALED(status))
printf(”Child %ld terminated e to signal %d znot caught\n”,
child,WTERMSIG(status));
}

strerror函数会返回一个指定的错误号的错误信息的字符串.

C. 管道通信中如何实现对管道的互斥使用父子进程的同步又是如何实现的

厂长,肠长,悬赏分给我吧,找了好久的呢~
.
~。父子进程的同步主要表现在两个方面:1,父进程读出之前确定管道中有数据,否则阻塞自己,这一点通过系统调用wait()函数既可以实现,当子进程结束时父进程才执行,那么此时管道中肯定有子进程写入的数据了;2,子进程在写入之前要确定管道中的数据已被父进程读出,否则不能写入或者阻塞自己。这可以通过进程见的互斥来间接办到,因为子进程间的互斥,所以每个子进程在执行开始都对管道pipe加锁,并且子进程在向管道中写入数据后还有调用sleep()系统用调用睡眠若干时间,那么就可保证父进程能够从管道中读出数据,然后下一子进程才能写入。

D. C语言中 怎么实现双线程 或者 父子线程啊

运行一个程序,这个运行实体就是一个“进程”。

例如,用鼠标双击IE浏览器的图标,你运行了一个IE“进程”。第一个窗未关,你又用鼠标双击IE浏览器的图标,又出来一个浏览器的窗。这时,你运行了同一个程序的两个进程。

对于自己写的程序也如此。运行它,这个运行实体就是一个“进程”。同时运行两个,就是两个进程。计算机分别对两个进程分配资源,直到进程结束,收回资源。

线程是进程里真真跑的线路,真真执行的运算,每个进程有一个主线程。进程里可以开第二第三条新的执行线路,gcc 用 pthread_create(),VC++ 用 CreateThread(), 这就叫双线程和多线程。进程是线程的容器,同一进程的线程共享它们进程的资源。线程里建的线程就是父子线程。

两个或多个进程协同工作时,需要互相交换信息,有些情况下进程间交换的少量信息,有些情况下进程间交换大批信息。这就要通讯。通讯方式不止一种。管道就是一种。VC++ 用 CreatePipe() 函数建立。

管道的实质是一个共享文件,可借助于文件系统的机制实现,创建、打开、关闭和读写.

一个进程正在使用某个管道写入或读出数据时,另一个进程就必须等待. 发送者和接收者双方必须知道对方是否存在,如果对方已经不存在,就没有必要再发送信息.,发送信息和接收信息之间要协调,当写进程把一定数量的数据写入管道,就去睡眠等待,直到读进程取走数据后,把它唤醒。

VC++ 线程例子:
#include <windows.h>
#include <iostream.h>

DWORD WINAPI fun1(LPVOID lp);
DWORD WINAPI fun2(LPVOID lp);
int piao=500;

int main()
{
HANDLE pthread1,pthread2;
pthread1=CreateThread(0,0,fun1,0,0,0);
pthread2=CreateThread(0,0,fun2,0,0,0);
CloseHandle(pthread1);
CloseHandle(pthread2);
Sleep(3000);
return 0;

}

DWORD WINAPI fun1(LPVOID lp)
{
while(1)
{

if(piao>0)
cout<< "thread-1-"<< piao--<<endl;
else
break;
}
return 0;
}

DWORD WINAPI fun2(LPVOID lp)
{
while(1)
{
if(piao>0)
cout<<"thread-2-"<<piao--<<endl;
else
break;
}
return 0;
}

===================================
建管道函数原形:
BOOL CreatePipe(
PHANDLE hReadPipe, // read handle
PHANDLE hWritePipe, // write handle
LPSECURITY_ATTRIBUTES lpPipeAttributes, // security attributes
DWORD nSize // pipe size
);

E. linux终端下使用pipe实现父子进程交互

看这个问题好久都没人回答。。。

挺简单的,fork一子一父进程,父进程循环读入文件内容,并写进道管道里面,子进程循环从管道接收然后打印出来。

撸码辛苦,望采纳。

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
intmain()
{
pid_tresult;
intn,num;
intpipe_fd[2];
intfd;
charbuf1[100],buf2[100];
memset(buf1,0,sizeof(buf1));
memset(buf2,0,sizeof(buf2));
fd=open("/home/w.c",O_RDONLY);
if(pipe(pipe_fd)<0)
{
printf("error! ");
return-1;
}
result=fork();
if(result<0)
{
printf("error! ");
exit(0);
}
elseif(result==0)
{
close(pipe_fd[1]);
while((n=read(pipe_fd[0],buf1,99))>0)
{
buf1[n]='';
printf("%s",buf1);
memset(buf1,0,sizeof(buf1));
}
}
else
{
close(pipe_fd[0]);
while((num=read(fd,buf2,99))>0){
write(pipe_fd[1],buf2,strlen(buf2));
}
waitpid(result,NULL,0);
}
close(pipe_fd[1]);
close(pipe_fd[0]);
close(fd);

return0;
}

F. Linux下利用匿名管道实现父子进程通信,要求从父进程输入整数 n 到子进程,算出1到n的偶数和

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>

intmain()
{
intfd[2];

//创建二个fd,fd[0]管道用于读,fd[1]管道用于写
pipe(fd);

//创建进程
pid_tpid=fork();
if(pid==0)
{
//子进程,读取整数n
intn;
read(fd[0],&n,sizeof(int));

//计算1-n的偶数和
intsum=0;
for(inti=1;i<=n;++i)
{
if(i%2==0)
{
sum+=i;
}
}

printf("Thesumofallevennumberfrom1to%dis%d ",n,sum);

//子进程工作完后使用exit(0)退出
exit(0);
}
else
{
//父进程,写入整数n
intn;
printf("Pleaseinputn:");
scanf("%d",&n);

write(fd[1],&n,sizeof(int));
}
}

Linux 环境下编译及测试结果如下:

G. 管道通信中如何实现对管道的互斥使用父子进程的同步又是如何实现的 消息通信的工作原理是什么

我们迪哥的答案:
当进程要与其它进程通讯时,可利用msgsnd()系统调用来发送消息。对于msgsnd()系统调用,核心检查消息队列描述符合许可权是否合法,消息长度是否超过系统规定的长度。通过检查后,核心为消息分配消息数据区,并将消息从用户消息缓冲区拷贝到消息数据区。分配消息首部,将它链入消息队列的末尾;在消息首部中填写消息的类型、大小以及指向消息数据区的指针等;还要修改消息队列头标中的数据(如消息队列中的消息数、字节数等)。然后,唤醒等待消息到来的睡眠进程。 消息的接收: 进程可利用msgrcv()系统调用,从指定消息队列中读一个消息。对于msgrcv()系统调用,先由核心检查消息队列标识符合许可权,继而根据用户指定的消息类型做相应的处理。消息类型msgtyp的参数可能有三种情况:当msgtyp=0时髦核心寻找消息队列中的第一个消息,并将它返回给调用进程;当msgtyp为正整数时,核心返回指定类型的第一个消息;当msgtyp为负整数时,核心应在其类型值小于或等于msgtyp绝对值的所有消息中,选出类型值最低的第一个消息返回。如果所返回消息的大小等于或小于用户的要求,核心便将消息正文拷贝到用户区,再从队列中删除该消息,并唤醒睡眠的发送进程;如果消息长度比用户要求的大,则系统返回出错信息。用户也可以忽略对消息大小的限制,此时,核心无需理会消息的大小而一概把消息内容拷贝到用户区。

H. linux下c++父子进程问题

你要详细看看waitpid()函数,它的功能就是让父程序在子程序完全运行完毕之后再运行,当然它还有非阻塞模式,这个函数一般放在父进程里面运行,它起到阻塞作用,当子进程结束,这个函数是会返回子进程的pid,这是结束的标志。
大概如此吧!哈哈!好久没有接触,可能有点不记得

阅读全文

与父子进程编译怎么实现相关的资料

热点内容
云服务器租用什么意思 浏览:147
程序员做中介怎么样 浏览:139
怎么把解压视频保存到手机 浏览:449
app欠费怎么查询 浏览:348
录音文件夹怎么压缩 浏览:896
编程培训机构学费 浏览:499
华为麦芒5服务器地址 浏览:744
怎么把app里面的app上锁 浏览:938
java数字运算 浏览:164
java读取上传的文件 浏览:373
xp怎么加密文档 浏览:273
压缩机风扇电机转速慢 浏览:88
文件服务器如何查看访问人员 浏览:127
绝佳买卖指标加密 浏览:758
git分支编译 浏览:156
51单片机c语言应用程序设计实例精讲 浏览:562
华为安卓手机编译器 浏览:48
怎样在打开微信前加密 浏览:666
旺旺聊天记录怎么加密 浏览:413
王安忆长恨歌pdf 浏览:621