栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

系统级程序设计(三):进程同步

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

系统级程序设计(三):进程同步

目录

1.exec函数族

【案例 1.1】

 2.进程退出

3.wait函数

【案例3. 1】

【案例 3.2】 

 4.waitpid函数

【案例 4.1】

【案例 4.2】


1.exec函数族
  • fork:子进程复制父进程的堆栈段和数据段,子进程一旦开始运行,它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再影响
  • exec:一个进程调用exec类函数,它本身就"死亡"了,系统把代码段替换成新的程序代码,废弃原有数据段和堆栈段,并为新程序分配新数据段与堆栈段

exec函数族中包含6个函数,分别为:

#include 
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[]);

【案例 1.1】
#include 
#include 
#include 
int main(){
    pid_t tempPid;
    tempPid=fork();
    if(tempPid == -1){   
        perror("fork error");
        exit(1);
    } else if(tempPid > 0) {   
        printf("parent process:pid=%dn", getpid());
    } else {   
        printf("child process:pid=%dn", getpid());
        //execl("/bin/ls","-a","-l","test_exec.c",NULL);	//①
        //execlp("ls","-a","-l","test_exec.c",NULL);	//②
        char *arg[]={"-a","-l","test_exec.c", NULL};	//③
        execvp("ls", arg);
        perror("error execn");
        printf("child process:pid=%dn", getpid());
    } //of if  
    return 0;
} //of main

结果: 

 2.进程退出
#include 
void exit(int status);
  • 参数说明:

(1)status:表示进程的退出状态,0表示正常退出,非0表示异常退出,一般用-1或1表示;
(2)为了可读性,标准C定义了两个宏:EXIT_SUCCESS和EXIT_FAILURE

Linux系统中有一个与exit()函数非常相似的函数:_exit()

#include 
void _exit(int status);
  • 区别:

1)_exit:系统会无条件停止操作,终止进程并清除进程所用内存空间及进程在内核中的各种数据结构;

2)exit:对_exit进行了包装,在调用_exit()之前先检查文件的打开情况,将缓冲区中的内容写回文件。相对来说exit比_exit更为安全

3.wait函数

【案例3. 1】

若子进程p1是其父进程p的先决进程,基于wait函数使得进程同步。

#include 
#include 
#include 
#include 
int main(){
	pid_t tempPid, tempW;
	tempPid = fork();
	if(tempPid == -1){
		perror("fork error");
		exit(1);
	}else if(tempPid == 0){//child
		sleep(3);
		printf("Child process, pid = %d, ppid = %dn", getpid(), getppid());
	}else{//parent 
		tempW = wait(NULL);
		printf("Catched a child process, pid = %d, ppid = %dn", tempW, getppid());
	}//of if
	printf("......finish......");
	return 0;
}//of main

结果:

【案例 3.2】 

使用wait同步进程,并使用宏获取子进程的返回值。

#include 
#include 
#include 
#include 
int main(){
    int tempStatus;
    pid_t tempPid, tempW;
    tempPid = fork();
    if(tempPid == -1){
        perror("fork error");
        exit(1);
    } else if(tempPid == 0){//子
        sleep(3);
        printf("Child process: pid=%dn",getpid());
        exit(5);
 	}  else{//父
        tempW = wait(&tempStatus);
        if(WIFEXITED(tempStatus)){
            printf("Child process pid=%d exit normally.n", tempW );
            printf("Return Code:%dn",WEXITSTATUS(tempStatus));
        } else {
            printf("Child process pid=%d exit abnormally.n", tempW);
        }//of if
    }//of if
    return 0;
}//of main

结果:

 4.waitpid函数

【案例 4.1】

父进程等待进程组中指定子进程,该进程不退出,则父进程一直阻塞。

#include 
#include 
#include 
#include 
int main(){
	pid_t tempPid, tempP, tempW;
	tempPid= fork();							//创建第一个子进程
	if (tempPid == -1){							
		perror("fork1 error");
		exit(1);
	} else if (tempPid == 0){						//子进程沉睡
		sleep(5);
		printf("First child process:pid=%dn", getpid());
	} else {						//父进程继续创建进程
		int i;
		tempP = tempPid;
		for (i = 0; i < 3; i++){					//由父进程创建3个子进程
			if ((tempPid = fork()) == 0){
				break;
			}//of if
		}//of for i
		if (tempPid == -1){						//出错
			perror("fork error");
			exit(2);
		} else if (tempPid == 0){					//子进程
			printf("Child process:pid=%dn", getpid());
			exit(0);
		} else {					//父进程
			tempW = waitpid(tempP, NULL, 0);			//等待第一个子进程执行
			if (tempW == tempP){
				printf("Catch a child Process: pid=%dn", tempW);
			}else{
				printf("waitpid errorn");
			}//of if
		}//of if
	}//of if
	return 0;
}//of main

结果:

【案例 4.2】

基于waitpid函数不断获取子进程的状态。

#include 
#include 
#include 
#include 
int main() {
	pid_t tempPid, tempW;
	tempPid = fork();
	if (tempPid == -1){
		perror("fork error");
		exit(1);
	} else if (tempPid == 0){
		sleep(3);
		printf("Child process:pid=%dn", getpid());
		exit(0);
	} else {
		do{
			tempW = waitpid(tempPid, NULL, WNOHANG);
			if (tempW == 0){
				printf("No child exitedn");
				sleep(1);
			}//of if
		} while (tempW == 0);
		if (tempW == tempPid){
			printf("Catch a Child process:pid=%dn", w);
		}else{
			printf("waitpid errorn");
		}//of if
	}//of if
	return 0;
}//of main

结果:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/875974.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号