Unix环境编程之 进程环境
发布时间:2020-12-15 16:40:45 所属栏目:安全 来源:网络整理
导读:(1)当执行程序时,main函数是的如何调用的 main函数原型是 int main( int argc, char *argv[]);argc是命令行参数,argv是指向参数的各个指针的数组。 #include"apue.h" int main(){ int i; for (i= 0 ;iargc;i++){ printf ( "argv[%d]:%sn" ,i,argv[i]);
(1)当执行程序时,main函数是的如何调用的main函数原型是int main(int argc,char *argv[]);
argc是命令行参数,argv是指向参数的各个指针的数组。
#include"apue.h"
int main()
{
int i;
for(i=0;i<argc;i++)
{
printf("argv[%d]:%sn",i,argv[i]);
exit(0);
}
//编译运行后如下:
zsj@zsj-virtual-machine:~/ccode$ cc -o 7-3 7-3.c
zsj@zsj-virtual-machine:~/ccode$ ./7-3 arg1 TEST foo
argv[0]:./7-3 //第一个指针指向文件
argv[1]:arg1
argv[2]:TEST
argv[3]:foo
内核执行c程序时(使用exec函数)调用main之前先调用一个特殊例程。例程从内核取得命令行参数 和环境变量值。(2)各种不同的进程终止方式#include<stdlib.h>
void exit(int status);
void_Exit(int status);
#include<unistd.h>
void _exit(int status);
这三个函数都可以用来正常终止一个程序:_exit 和_Exit立即进入内核,exit则执行一些清理操作(调用执行各终止处理程序,关闭所有标准I/O流)三个函数都带一个整型参数称为终止状态。 (3)c程序的存储空间布局text:正文段。这是由CPU执行的机器指令部分,正文段是可共享的,正文段常常是只读的。初始化数据段。出现在任何函数以外的声明。非初始化数据段。开始执行程序之前内核将此段中的数据初始化为0或空指针。栈:自动变量以及每次函数调用时所保存的信息都放在栈中。递归函数每次调用自身都使用一个新的栈帧堆:通常在堆中进行动态存储分配。(4)如何分配存储空间#include<stdlib.h>
void *malloc(size_t size);
void *calloc(size_t nobj,size_t size);//为指定数量具有指定长度的对象分配存储空间。
void *realloc(void *ptr,size_t newsize);
void free(*ptr);
三个函数返回值,若成功则返回非空指针,出错则返回null
(5)创建进程以及进程属性进程标识符每个进程都有一个非负整数表示的唯一进程ID。进程ID可以重用,当一个进程终止时,进程ID就可以重新使用了。 fork函数#include<unistd.h>
pid_t fork(void)
返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1
由fork创建的新进程称为子进程。fork函数被调用一次,但返回两次。 子进程和父进程继续执行fork()之后的指令。子进程是父进程的副本。获得父进程的数据空间、堆栈、父子进程并不共享这些存储部分。父子进程共享正文段。 #include<stdio.h>
#include"apue.h"
#include<myerror.h>
int glob=6;
char buf[]="a write to stdoutn";
int main(void)
{
int var;
pid_t pid;
var=88;
if(write(STDOUT_FILENO,buf,sizeof(buf)-1)!=sizeof(buf)-1)
err_sys("write error");
printf("before forkn");
if(pid=fork()<0)
{
err_sys("fork error");
}
else if(pid==0)
{
glob++;
var++;
}
else{
sleep(2);
}
printf("pid= %d,glob=%d,var=%dn",getpid(),glob,var);
exit(0);
}
zsj@zsj-virtual-machine:~/ccode$ cc 8-1.c
zsj@zsj-virtual-machine:~/ccode$ ./a.out
a write to stdout
before fork
pid=14828,glob=7,var=89 //子进程的变量变了
pid=14827,glob=6,var=88 //父进程得变量值没变
zsj@zsj-virtual-machine:~/ccode$ ./a.out >temp.out
zsj@zsj-virtual-machine:~/ccode$ cat temp.out
a write to stdout
before fork
pid=14830,var=89
before fork
pid=14829,var=88
zsj@zsj-virtual-machine:~/ccode$
在fork之后 是父进程还是子进程先执行时不确定的。这取决于内核所使用的调度算法。如果要求父子进程之间相互同步,则要求某种形式的进程间通信。父进程使自己休眠两秒,以使子进程先执行。write函数是不带缓冲的。因为在fork之前调用write,所以其数据写到标准输出一次,但是标准库是带缓冲的.如果标准输出连到终端设备,则它是行缓冲的,否则它是全缓冲的。当以交互运行该程序时,只得到printf一行,原因是标准输出的缓冲区由换行符冲洗。而将标准输出重定向到一个文件时,却得到printf输出两行,其原因是,在fork之前调用了printf一次,但当调用fork时,该行数据仍在缓冲区中,然后在父进程数据空间被复制到子进程中,当每个进程终止时,最终会冲洗缓冲区中的副本。(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容