实验六 进程基础

时间:2020-05-06
本文章向大家介绍实验六 进程基础,主要包括实验六 进程基础使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

实验六 进程基础

项目 内容
这个作业属于哪个课程 课程链接(点击查看)
这个作业的要求在哪里 作业要求
学号-姓名 17043232-邹勇贵
作业学习目标 1.掌握Linux系统环境C语言编程概念 2.学习Linux系统进程概念

实验六 进程基础

实验内容

  1. 请举例说明静态链接库的创建与使用。

    生成两个.o文件。
    
    生成app文件使用静态库
    
    在程序中使用静态库
    
  2. 请举例说明共享库的创建与使用。

    生成libxxx.so文件
    
    程序的配置
    
    生成app文件
    
    使用共享库
    
  3. 编程实现一个简单文件复制命令。

    **cope.c**
    #include<stdio.h>
    
    #include<stdlib.h>
    
    #include<string.h>
    
    #include<dirent.h>
    
    #include<sys/stat.h>
    
    #include<unistd.h>
    
     
    
    int is_dir(char* path);//判断是否是目录  是返回1 否则返回0
    
    int copy_file(char* srcPath,char *destPath);//复制文件  成功返回0 否则返回 -1
    
    int copy_folder(char* srcPath,char *destPath);//复制文件夹  成功返回0 否则返回 -1
    
     
    
    int main(int argc,char *argv[])  //argv[1] 源文件  argv[2] 目标文件
    
    {
    
    	if(argc != 3)
    
    	{
    
    		printf("Usage srcfile destfile\n");
    
    		return -1;
    
    	}
    
    	char* srcPath=argv[1];
    
    	char* destPath=argv[2];
    
     
    
    	if(is_dir(srcPath)) //文件夹的拷贝
    
    	{
    
    		copy_folder(srcPath,destPath);
    
    	}
    
    	else
    
    	{
    
    		if(access(destPath,F_OK) == 0)  //保证destPath是未存在的目录
    
    		{
    
    			printf("目标文件已存在\n");
    
    			return -1;
    
    		}
    
    		copy_file(srcPath,destPath);//文件进行拷贝
    
    	}
    
    	return 0;
    
     
    
    }
    
    //判断是否是目录  是返回1 否则返回0
    
    int is_dir(char* path)
    
    {
    
    	struct stat st;
    
    	stat(path,&st);
    
    	if(S_ISDIR(st.st_mode))
    
    		return 1;
    
    	else
    
    		return 0;
    
    }
    
     
    
    //复制文件  成功返回0 否则返回 -1
    
    int copy_file(char* srcPath,char *destPath)
    
    {
    
    	char Buf[1024] = {0};
    
    	int count_read = 0;
    
    	long fp_src_ltell = 0,fp_src_atell = 0;
    
    	FILE* fp_src = fopen(srcPath,"r");//只读方式打开
    
    	FILE* fp_dst = fopen(destPath,"w");//只写方式打开
    
    	if(fp_dst ==NULL || fp_src == NULL)
    
    	{
    
    		printf("文件打开有问题\n");
    
    		return -1;
    
    	}
    
    	while(1)
    
    	{
    
    		memset(Buf,0,sizeof(Buf));
    
    		fp_src_ltell = ftell(fp_src); //上一次文件指针位置
    
    		count_read = fread(Buf,sizeof(Buf),1,fp_src);
    
    		fp_src_atell = ftell(fp_src); //当前文件指针位置
    
    		if(count_read<1) //异常或到达末尾结束
    
    		{
    
    			if(feof(fp_src))
    
    			{
    
    				long temp = fp_src_atell - fp_src_ltell;
    
    				fwrite(Buf,temp,1,fp_dst); //成功
    
    				return 0;
    
    			}
    
    			else if(ferror(fp_src))
    
    			{
    
    				perror("fread error:");
    
    				return -1;
    
    			}
    
    		}
    
    		fwrite(Buf,sizeof(Buf),1,fp_dst);
    
    	}
    
    	return 0;
    
    }
    
     
    
    //复制文件夹
    
    int copy_folder(char* srcPath,char *destPath)
    
    {
    
    	char newsrcPath[4096];
    
    	char newdestPath[4096];
    
    	
    
    	if (mkdir(destPath,0777))//如果不存在就用mkdir函数来创建
    
    	{
    
    		printf("目标文件已存在\n");
    
    		return -1;
    
    	}
    
    	
    
    	DIR* srcDp = opendir(srcPath);
    
    	if(srcDp == NULL)
    
    	{
    
    		printf("打开文件夹[%s]失败!\n",srcPath);
    
    		return -1;
    
    	}
    
    	struct dirent * srcDirent = NULL;
    
    	int flag = 0;
    
    	while(srcDirent = readdir(srcDp))
    
    	{
    
    		flag++;
    
    		if(flag>2) //去除隐藏文件 . ..
    
    		{
    
    			bzero(newsrcPath,sizeof(newsrcPath)); //清空
    
    			bzero(newdestPath,sizeof(newdestPath));
    
    				
    
    			sprintf(newsrcPath,"%s/%s",srcPath,srcDirent->d_name);//保存新的文件路径
    
    			sprintf(newdestPath,"%s/%s",destPath,srcDirent->d_name);
    
    			
    
    			if(srcDirent->d_type == DT_DIR) //文件夹的拷贝
    
    				copy_folder(newsrcPath,newdestPath);
    
    			else 					     	 //普通文件
    
    				copy_file(newsrcPath,newdestPath);
    
    		}
    
    			
    
    	}
    
    	return 0;
    
    }
    
    
  4. 使用fork创建一个子进程,进程创建成功后父子进程分别输出不同的内容。

    删除了fflush();
    可以发现父进程,子进程从开始到后面的自己灭亡就只占一个进程。
    
  5. 使用fork创建多个子进程。

    产生了3个子进程
    
  6. 在 fork 之前以写的方式创建了一个文件 test.txt。然后 fork 出的子进程立即向文件中写入“world”,然后睡眠5秒。而父进程在 fork 后睡眠3秒后向 test.txt 写入 "hello",并关闭描述符。子进程恢复后,又向 test.txt 文件中写入 "lalala"后关闭描述符,结束。

    写入fork3.c的代码
    
  7. 分别在主函数中使用execvp启动ls命令以及使用fork函数产生子进程调用execvp启动ls

    1,使用execvp启动ls命令

    生成-o execls文件运行,使用execvp启动ls命令
    
    execls.c
    

    2,使用fork函数产生子进程调用execvp启动ls

    ![image-20200504011510198](C:\Users\彦祖\Desktop\实验三 Linux系统用户管理及VIM配置 .assets\image-20200504011510198.png)

  8. 创建5个僵尸进程,并在终端通过ps axf命令查看僵尸进程信息。

    端通过ps axf命令查看僵尸进程

  9. 通过wait来清理僵尸进程。

  10. 父进程通过waitpid函数等待特定子进程结束,若该子进程不结束,父进程一直阻塞。

原文地址:https://www.cnblogs.com/qq1105676570/p/12837830.html