LINUX 进程控制程序设计

原创 2013年12月03日 11:12:56

1、获取ID

//包含两个头文件

#include <sys/types.h>
#include <unistd.h>


vpid_t getpid(void)       //获取本进程ID。

      //vpid_t是Linux下的进程号类型,其实是宏定义的unsigned int类型

头文件:旧版本\Linux系统下:unistd.h,在VC++6.0下可以用process.h
函数原型:旧的原型为pid_t getpid(void);,推荐使用int _getpid( void );这种形式。注意,函数名第一个字符是下划线。
函数说明:getpid函数用来取得目前进程的进程识别码,许多程序利用取到的此值来建立临时文件,以避免临时文件相同带来的问题。
返回值:目前进程的进程识别码

pid_t getppid(void)      //获取父进程ID。

      //pid_t是Linux下的进程号类型,也就是Process ID _ Type 的缩写。 其实是宏定义的unsigned int类型

相关函数 fork,kill,getpid
表头文件 #include<unistd.h>
定义函数 pid_t getppid(void);
函数说明 getppid()用来取得目前进程的父进程识别码。
返回值 目前进程的父进程识别码。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
    printf( "PID = %d\n", getpid() );
    printf( "PPID = %d\n", getppid() );
    return 0;
}


2、进程创建-fork

#include <unistd.h>

#include <sys/types.h>
pid_t fork(void)

功能:创建子进程
fork的奇妙之处在于它被调用一次,却返回两次,它可能有三种不
同的返回值:
1). 在父进程中,fork返回新创建的子进程的PID;
2). 在子进程中,fork返回0;
3). 如果出现错误,fork返回一个负值

头文件:

#include<unistd.h>

#include<sys/types.h>

函数原型:pid_t forkvoid);(pid_t 是一个宏定义,其实质是int 被定义在#include<sys/types.h>中)

返回值: 若成功调用一次则返回两个值,子进程返回0,返回子进程ID;否则,出错返回-1

fork.c

#include <sys/types.h>
#include <unistd.h>
main()
{
    pid_t pid;
    /*此时仅有一个进程*/
    pid=fork();
    /*此时已经有两个进程在同时运行*/
    if(pid<0)
         printf("error in fork!");
    else if(pid==0)
         printf("I am the child process, ID is %d\n",getpid());
    else
         printf("I am the parent process,ID is %d\n",getpid());
}

代码解读:在pid=fork()之前,只有一个进程在执行,但在这条语句执行之后,就变成两个进程在执行了,这两个进程的共享代码段,将要执行的下一条语句都是if(pid==0)。 两个进程中,原来就存在的那个进程被称作“父进程”,新出现的那个进程被称作“子进程”,父子进程的区别在于进程标识符(PID)不同。


3、进程创建-vfork

#include <sys/types.h>
#include <unistd.h>
pid_t vfork(void)

功能:创建子进程。


fork PK vfork

区别:
1. fork:子进程拷贝父进程的数据段
vfork:子进程与父进程共享数据段
2. fork:父、子进程的执行次序不确定
vfork:保证子进程先运行,在调用exec或_exit之前与 父进程数据是共享的,在它调用exec或_exit之后 父进程才可能被调度运行。

3、当需要改变共享数据段中变量的值,则拷贝父进程。

#include <unistd.h>
#include <stdio.h>
int main(void)
{
    pid_t pid;
    int count=0;
    pid = vfork();
    count++;
    printf( “count = %d\n", count );
    return 0;
}


4、exec函数族

exec用被执行的程序替换调用它的程序。
区别:
fork创建一个新的进程,产生一个新的PID。exec启动一个新程序,替换原有的进程,因此进程的PID不会改变。

说是exec系统调用,实际上在Linux中,并不存在一个exec()的函数形式,exec指的是一组函数,一共有6个,分别是:

#include <unistd.h>

extern char **environ;

int execl(const char *path, const char *arg, ...);

int execlp(const char *file, const char *arg, ...);

int execle(const char *path, const char *arg, ..., char * const envp[]);

int execv(const char *path, char *const argv[]);

int execvp(const char *file, char *const argv[]);

int execve(const char *path, char *const argv[], char *const envp[]);

其中只有execve是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。

1)

#include<unistd.h>
int execl(const char * path,const char * arg1, ....)
参数:
path:被执行程序名(含完整路径)。
arg1 – argn: 被执行程序所需的命令行参数,含程序名。以空指针(NULL)结束。
函数说明:execl()其中后缀"l"代表list也就是参数列表的意思,第一参数path字符指针所指向要执行的文件路径, 接下来的参数代表执行该文件时传递的参数列表:argv[0],argv[1]... 最后一个参数须用空指针NULL作结束。

execl.c

#include <unistd.h>
main()
{
    execl(“/bin/ls”,”ls”,”-al”,”/etc/passwd”,(char * )0);
}

2)

#include<unistd.h>
int execlp(const char * path,const char * arg1, ...)

函数说明:execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。如果用常数0来表示一个空指针,则必须将它强制转换为一个字符指针,否则将它解释为整形参数,如果一个整形数的长度与char * 的长度不同,那么exec函数的实际参数就将出错。如果函数调用成功,进程自己的执行代码就会变成加载程序的代码,execlp()后边的代码也就不会执行了.
参数:
path:被执行程序名(不含路径,将从path环境变量中查找该程序)。
arg1 – argn: 被执行程序所需的命令行参数,含程序名。以空指针(NULL)结束。

返回值:如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。

execlp.c

#include<unistd.h>
main()
{
    execlp(”ls”,”ls”,”-al”,”/etc/passwd”,(char *)0);
}

3)

#include<unistd.h>
int execv (const char * path, char * const argv[ ])

功 能: 装入并运行其它程序的函数
参数:
path:被执行程序名(含完整路径)。
argv[]: 被执行程序所需的命令行参数数组。

#include <unistd.h>
main()
{
    char * argv[ ]={“ls”,”-al”,”/etc/passwd”,(char*)0};
    execv(“/bin/ls”,argv);
}

4)

#include<unistd.h>
int execvp(const char *file ,char * const argv []);
函数说明:
execvp()会从PATH 环境变量所指的目录中查找符合参数file 的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件。
返回值:
如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。
错误代码:
EACCES
1. 欲执行的文件不具有用户可执行的权限。
2. 欲执行的文件所属的文件系统是以noexec 方式挂上。
3.欲执行的文件或script翻译器非一般文件。
EPERM
1.进程处于被追踪模式,执行者并不具有root权限,欲执行的文件具有SUID 或SGID 位。
2.欲执行的文件所属的文件系统是以nosuid方式挂上,欲执行的文件具有SUID 或SGID 位元,但执行者并不具有root权限。
E2BIG 参数数组过大
ENOEXEC 无法判断欲执行文件的执行文件格式,有可能是格式错误或无法在此平台执行。
EFAULT 参数filename所指的字符串地址超出可存取空间范围。
ENAMETOOLONG 参数filename所指的字符串太长。
ENOENT 参数filename字符串所指定的文件不存在。
ENOMEM 核心内存不足
ENOTDIR 参数filename字符串所包含的目录路径并非有效目录
EACCES 参数filename字符串所包含的目录路径无法存取,权限不足
ELOOP 过多的符号连接
ETXTBUSY 欲执行的文件已被其他进程打开而且正把数据写入该文件中
EIO I/O 存取错误
ENFILE 已达到系统所允许的打开文件总数。
EMFILE 已达到系统所允许单一进程所能打开的文件总数。
EINVAL 欲执行文件的ELF执行格式不只一个PT_INTERP节区
EISDIR ELF翻译器为一目录
ELIBBAD ELF翻译器有问题。

execvp.c

#include<unistd.h>
main()
{
   char * argv[ ] ={ “ls”,”-al”,”/etc/passwd”,0};
   execvp(“ls”,argv);
}

5)

#include<unistd.h>

int execve(const char * filename,char * const argv[ ],char * const envp[ ]);

函数说明:execve()用来执行参数filename字符串所代表的文件路径,第二个参数是利用数组指针来传递给执行文件,并且需要以空指针(NULL)结束,最后一个参数则为传递给执行文件的新环境变量数组。

返回值:

如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。
错误代码EACCES
1. 欲执行的文件不具有用户可执行的权限。
2. 欲执行的文件所属的文件系统是以noexec 方式挂上。
3.欲执行的文件或script翻译器非一般文件。
EPERM
1.进程处于被追踪模式,执行者并不具有root权限,欲执行的文件具有SUID 或SGID 位。
2.欲执行的文件所属的文件系统是以nosuid方式挂上,欲执行的文件具有SUID 或SGID 位元,但执行者并不具有root权限。
E2BIG 参数数组过大
ENOEXEC 无法判断欲执行文件的执行文件格式,有可能是格式错误或无法在此平台执行。
EFAULT 参数filename所指的字符串地址超出可存取空间范围。
ENAMETOOLONG 参数filename所指的字符串太长。
ENOENT 参数filename字符串所指定的文件不存在。
ENOMEM 核心内存不足
ENOTDIR 参数filename字符串所包含的目录路径并非有效目录
EACCES 参数filename字符串所包含的目录路径无法存取,权限不足
ELOOP 过多的符号连接
ETXTBUSY 欲执行的文件已被其他进程打开而且正把数据写入该文件中
EIO I/O 存取错误
ENFILE 已达到系统所允许的打开文件总数。
EMFILE 已达到系统所允许单一进程所能打开的文件总数。
EINVAL 欲执行文件的ELF执行格式不只一个PT_INTERP节区
EISDIR ELF翻译器为一目录
ELIBBAD ELF翻译器有问题。
execve.c

#include<unistd.h>
main()
{
    char * argv[ ]={"ls","-al","/etc/passwd",(char *)0};
    char * envp[ ]={"PATH=/bin",0};
    execve("/bin/ls",argv,envp);
}

6)

#include<unistd.h>

int execle(const char * path,const char * arg,....,char *const envp[]);

函数说明:
execl()用来执行参数path字符串所代表的文件路径,并为新程序复制最后一个参数所指示的环境变量。接下来的参数代表执行该文件时传递过去的argv(0)、argv[1]……,最后一个参数必须用空指针(NULL)作结束。
返回值:
如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。

5、

#include <stdlib.h>
int system( const char* string )
功能:
调用fork产生子进程,由子进程来调用
/bin/sh -c string来执行参数string所代表
的命令。

system.c

#include <stdlib.h>
void main()
{
    system(“ls -al /etc/passwd”);
}
6、进程等待
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait (int * status)
功能:
阻塞该进程,直到其某个子进程退出。

wait.c

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
void main()
{
   pid_t pc,pr;
   pc=fork();
   if (pc==0){ /* 如果是子进程 */
       printf(“This is child process with pid of %d\n”,getpid());
       sleep(10); /* 睡眠10秒钟 */
   }
   else if (pc>0){ /* 如果是父进程 */
       pr=wait(NULL); /* 等待 */
       printf("I catched a child process with pid of %d\n"),pr);
   }
   exit(0);
}



Linux进程控制程序设计

进程控制理论基础 定义:进程是一个具有独立功能的程序的一次性活动。 特点:动态性、并发性、独立性、异步性 进程ID(PID):标识进程的唯一数字。父进程的ID(P...
  • qq_27522735
  • qq_27522735
  • 2016年12月06日 16:39
  • 175

linux进程控制块

进程在操作系统中都有一个户口,用于表示这个进程。这个户口操作系统被称为PCB(进程控制块),在linux中具体实现是 task_struct数据结构,它记录了一下几个类型的信息: 1.状态信息,例如这...
  • wangwenwen
  • wangwenwen
  • 2013年05月03日 11:25
  • 4953

PCB(进程控制块)以及Linux下的进程控制块task_struct

进程控制块中的信息: 1.进程标识符:进程标识符是惟一地标识一个进程。一个进程通常有两种标识符   (1).内部表示符:在所有的操作系统中,都为每一个进程赋予了一个惟一的数字标识符,它通常是一个进程的...
  • wangiijing
  • wangiijing
  • 2016年06月04日 18:53
  • 851

【Linux】进程控制块PCD结构(tack_struct)

tack_struct结构图: 一、task_struct 结构描述 1.进程状态(State) 进程执行时,它会根据具体情况改变状态。进程状态是调度和对换的依据。Linux...
  • Scenlyf
  • Scenlyf
  • 2016年06月12日 10:23
  • 6457

Linux下进程控制函数

Linux下进程控制函数
  • u014646950
  • u014646950
  • 2016年08月11日 09:19
  • 847

Linux下的进程控制块—task_struct

Linux下的进程控制块     进程:程序的执行就是进程。也可以把进程看成一个独立的程序,在内存中有其对应的代码空间和数据空间,一个进程所拥有的数据和代码只属于自己。进程是资源分配的基本单位,...
  • zw_1510
  • zw_1510
  • 2016年06月09日 13:27
  • 919

UNIX/Linux-进程控制(实例入门篇)

UNIX进程   进程标识符 要想对进程控制,必须得获取进程的标识。每个进程都有一个非负整数表示的唯一进程ID,虽然是唯一的,但是进程ID可以重用。当一个进程终止后,其进程ID就可以...
  • yang_yulei
  • yang_yulei
  • 2013年12月18日 22:38
  • 6399

linux进程及进程控制

Linux进程控制   程序是一组可执行的静态指令集,而进程(process)是一个执行中的程序实例。利用分时技术,在Linux操作系统上同时可以运行多个进程。分时技术的基本原理是把...
  • a623891391
  • a623891391
  • 2015年09月07日 11:33
  • 1980

[Linux]Linux Shell多进程并发以及并发数控制

Unix是一个多任务系统,允许多用户同时运行多个程序。shell的元字符&提供了在后台运行不需要键盘输入的程序的方法。输入命令后,其后紧跟&字符,该命令就会被送往到linux后台执行,而终端又可以继续...
  • yeweiouyang
  • yeweiouyang
  • 2016年09月12日 12:56
  • 10567

linux进程资源限制

概念: 1.进程的资源限制通常是在系统初始化时有0进程建立,然后由每个后续进程继承,其中一些资源可以用getrlimit和setrlimt函数查询和更改 2.在更改资源限制时,须遵守下列三条规则 (1...
  • daiyudong2020
  • daiyudong2020
  • 2016年02月05日 17:23
  • 897
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LINUX 进程控制程序设计
举报原因:
原因补充:

(最多只允许输入30个字)