IO进程线程复习:进程线程

1.进程的创建

#include<myhead.h>

int main(int argc, const char *argv[])
{
	printf("hello world\n");//父进程执行的内容
	int num=520;//在父进程中定义的变量

	pid_t pid=fork();//创建子进程

	if(pid>0)
	{
		while(1)
		{
			printf("我是父进程,num=%d\n",num);
			sleep(1);
		}
	
	}
	else if(pid==0)
	{
		num=1314;//更改子进程中的num的值
		while(1)
		{
			printf("我是子进程,num=%d\n",num);
			sleep(1);
		}
	
	}else
	{
		perror("fork error");
		return -1;
	}

	
	return 0;
}

2.进程号的获取

#include<myhead.h>

int main(int argc, const char *argv[])
{
	pid_t pid=-1;
	//创建一个子进程
	pid=fork();

	//判断父子进程
	if(pid>0)
	{
		printf("我是父进程,当前进程id号:%d,ppid=%d\n",getpid(),getppid());
	}
	else
	{
		printf("我是子进程,当前进程id号:%d,ppid=%d\n",getpid(),getppid());
	
	}
	while(1);

	return 0;
}

3.回收进程资源wait

#include<myhead.h>

int main(int argc, const char *argv[])
{
	pid_t pid=-1;
	//创建一个子进程
	pid=fork();

	//判断父子进程
	if(pid>0)
	{
		printf("我是父进程,当前进程id号:%d,ppid=%ildid=%d\n",getpid(),getppid(),pid);

		//调用进程退出函数
		//exit(EXIT_SUCCESS);//会刷新缓冲区
		//_exit(EXIT_SUCCESS);//不会刷新缓冲区
	}
	else
	{
		printf("我是子进程,当前进程id号:%d,ppid=%d\n",getpid(),getppid());
		sleep(3);
		exit(EXIT_SUCCESS);//会刷新缓冲区
	
	}
	wait(NULL);//阻塞等待子进程结束
	printf("已经成功回收子进程\n");
	while(1);

	return 0;
}

4.waitpid回收僵尸进程

#include<myhead.h>

int main(int argc, const char *argv[])
{
	pid_t pid=fork();//创建子进程
	if(pid>0)
	{
		printf("我是父进程\n");
		//sleep(5);
	}
	else if(pid==0)
	{
		printf("我是子进程\n");
		sleep(3);

		//退出子进程
		exit(EXIT_SUCCESS);
	}
	else
	{
		perror("fork error");
		return -1;
	}

	//使用waitpid以非阻塞的形式回收僵尸进程
	if(waitpid(-1,NULL,WNOHANG)>0)
	{
		printf("成功回收一个僵尸进程\n");
	}
	printf("父进程要结束了\n");
	return 0;
}

5.使用多进程完成两个文件的拷贝,父进程拷贝前一半,子进程拷贝后一半,父进程回收子进程资源。

#include<myhead.h>
//定义获取文件长度的函数
int get_file_len(const char *srcfile,const char *destfile)
{
	//以只读的形式打开源文件
	int srcfd,destfd;
	if((srcfd=open(srcfile,O_RDONLY))==-1)
	{
		perror("open srcfile error");
		return -1;
	}
	//以只写和创建的形式打开目标文件
	if((destfd=open(destfile,O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
	{
		perror("open destfile error");
		return -1;
	}
	//求源文件的大小
	int len=lseek(srcfd,0,SEEK_END);

	//关闭两个文件
	close(srcfd);
	close(destfd);

	return len;
}

//定义文件拷贝函数
int copy_file(const char *srcfile,const char *destfile,int start,int len)
{
	//以只读的形式打开源文件,以只写的形式打开目标文件
	int srcfd,destfd;
	if((srcfd=open(srcfile,O_RDONLY))==-1)
	{
		perror("srcfile open error");
		return -1;
	}
	if((destfd=open(destfile,O_WRONLY))==-1)
	{
		perror("destfile open error");
		return -1;
	}

	//移动文件的光标
	lseek(srcfd,start,SEEK_SET);
	lseek(destfd,start,SEEK_SET);

	//完成拷贝工作
	char buf[128]="";
	int sum=0;
	while(1)
	{
		int res=read(srcfd,buf,sizeof(buf));
		sum+=res;//将每次读取的数据放入sum中
		if(sum>=len||res==0)
		{
			write(destfd,buf,res-(sum-len));//将最后一次的内容写入
			break;
		}
		//将读取的数据写入目标文件
		write(destfd,buf,res);
	}

	//关闭文件
	close(srcfd);
	close(destfd);

	return 0;
}
int main(int argc, const char *argv[])
{
	//判断外部传参
	if(argc!=3)
	{
		printf("input file error\n");
		printf("usage:./a.out srcfile destfile\n");
		return -1;
	}

	//定义变量获取源文件长度
	int len=get_file_len(argv[1],argv[2]);

	//创建多进程
	pid_t pid=fork();

	//皮带父子进程
	if(pid>0)
	{
		//父进程
		copy_file(argv[1],argv[2],0,len/2);//父进程拷贝前一半

		//阻塞等待子进程结束
		wait(NULL);
	}
	else if(pid==0)
	{
		//子进程	
		copy_file(argv[1],argv[2],len/2,len-len/2);//子进程拷贝后一半

		//退出进程
		exit(EXIT_SUCCESS);
	}
	else
	{
		perror("fork error");
		return -1;
	}
	printf("拷贝成功\n");
	return 0;
}

6.守护进程的创建

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//创建子进程
	pid_t pid=-1;
	pid=fork();

	//判断
	if(pid>0)
	{
		//父进程
		exit(EXIT_SUCCESS);
	}
	else if(pid==0)
	{
		//子进程
		//1.将组id和会话id改成自己
		setsid();
		//2.更改操作目录为根目录
		chdir("/");
		//3.修改创建文件的掩码
		umask(0);
		//4.将标准输入、标准输出和标准出错重定向到指定文件
		int fd=-1;
		if((fd=open("./logtest.txt",O_RDWR|O_CREAT|O_APPEND))==-1)
		{
			perror("open error");
			return -1;
		}

		dup2(fd,0);
		dup2(fd,1);
		dup2(fd,2);

		while(1)
		{
			printf("hello world\n");
			fflush(stdout);//刷新缓冲区

			sleep(1);
		}

	}
	else
	{
		perror("fork error");
		return -1;
	}
	return 0;
}

7.创建多线程

#include<myhead.h>
//定义分之线程
void *task(void *arg)
{
	while(1)
	{
		printf("我是分支线程\n");
		sleep(1);
	}
}
int main(int argc, const char *argv[])
{
	//定义一个线程号变量
	pthread_t tid=-1;
	//创建线程
	if((pthread_create(&tid,NULL,task,NULL))!=0)
	{
		printf("pthread_creat error\n");
		return -1;
	}
	//下面的程序是主线程内容
	while(1)
	{
		printf("我是主线程,tid=%ld\n",tid);
		sleep(1);
	}
	return 0;
}

8.多线程的综合应用

#include<myhead.h>
//定义分支线程
void *task(void *arg)
{
	while(1)
	{
		printf("我是分支线程,tid=%#lx\n",pthread_self());
		sleep(3);

		//退出线程
		pthread_exit(NULL);

		printf("111111111111111\n");
	}
}
int main(int argc, const char *argv[])
{
	//定义一个线程号变量
	pthread_t tid=-1;
	//创建线程
	if((pthread_create(&tid,NULL,task,NULL))!=0)
	{
		printf("pthread_create error\n");
		return -1;
	}
	//下面的程序是主线程的内容
	printf("我是主线程,tid=%#lx,主线程号:%#lx\n",tid,pthread_self());

	//回收线程退出的资源,阻塞等待对应的线程退出
	if(pthread_join(tid,NULL)==0)
	{
		printf("成功回收了一个线程\n");
	}

	//将线程设置程分离态
	pthread_detach(tid);

	printf("主线程要退出了\n");
	sleep(5);
	return 0;
}

9.向指定线程发送取消信号

#include<myhead.h>
//定义分支线程1
void *task1(void *arg)
{
	while(1)
	{
		printf("我是线程1,我想活着\n");
		sleep(1);
	}
}
//定义分支线程2
void *task2(void *arg)
{
	while(1)
	{
		//设置忽略取消信号
		if(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL)!=0)
		{
			printf("set error\n");
			return NULL;
		}

		printf("我是线程2,我想活着\n");
		sleep(1);
	}
}

int main(int argc, const char *argv[])
{
	//定义线程号变量
	pthread_t tid1,tid2;
	//创建两个线程
	if(pthread_create(&tid1,NULL,task1,NULL)!=0)
	{
		printf("pthread_create tid1 error\n");
		return -1;
	}
	if(pthread_create(&tid2,NULL,task2,NULL)!=0)
	{
		printf("pthread_create tid2 error\n");
		return -1;
	}
	
	//主线程
	printf("tid1=%#lx,tid2=%#lx\n",tid1,tid2);
	sleep(5);
	printf("线程1可以死了\n");
	pthread_cancel(tid1);

	sleep(5);
	printf("线程2也可以死了\n");
	pthread_cancel(tid2);

	//回收线程资源
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	return 0;
}

10.向分支线程中传递数据

#include<myhead.h>
//定义要传递的结构体类型
struct Info
{
	char *p;
	char *q;
	int s;
	int l;
	int value;
};

//定义全局变量
int key=1314;

//定义分支线程
void *task(void *arg)
{
	printf("key=%d\n",++key);

	//处理主线程中传过来的数据
	struct Info buf=*((struct Info*)arg);
	printf("buf.p=%s,buf.q=%s,buf.s=%d,buf.l=%d\n",buf.p,buf.q,buf.s,buf.l);

	//想要将分支线程中的数据传给主线程
	(*((struct Info*)arg)).value=5201314;
}
int main(int argc, const char *argv[])
{
	pthread_t tid;
	int num=520;

	//要传递给分支线程的数据
	char *srcfile="./02text.txt";
	char *destfile="./17test.txt";
	int start=0;
	int len=520;

	//定义一个结构体变量
	struct Info buf={srcfile,destfile,start,len};

	//创建线程
	if(pthread_create(&tid,NULL,task,&buf)!=0)//向分支线程传递一个数据
	{
		printf("tid create error\n");
		return -1;
	}

	//主线程中使用全局变量
	printf("key=%d\n",++key);
	sleep(1);

	//输出分支线程给的数据
	printf("buf.value=%d\n",buf.value);

	//回收资源
	pthread_join(tid,NULL);
	return 0;
}

11.使用多线程完成两个文件的拷贝,第一个线程拷贝前一半,第二个线程拷贝后一半,主线程回收两个线程的资源。

#include<myhead.h>
//创建结构体用于主线程往分支线程传参
typedef struct Info
{
	int length;
	const char *src;
	const char *dest;
}SI;
int get_file_len(const char *srcfile,const char *destfile);
int copy_file(const char *srcfile,const char *destfile,int start,int len);

//创建子线程1
void *task1(void *arg)
{
	copy_file(((SI *)arg)->src,((SI *)arg)->dest,0,((SI *)arg)->length/2);//子线程1拷贝前一半
	pthread_exit(NULL);//退出线程
}
//创建子线程2
void *task2(void *arg)
{
	copy_file(((SI *)arg)->src,((SI *)arg)->dest,((SI *)arg)->length/2,((SI *)arg)->length-((SI *)arg)->length/2);//子线程2拷贝后一半
	pthread_exit(NULL);//退出线程
}
int main(int argc, const char *argv[])
{
	//判断外部传参是否合法
	if(argc!=3)
	{
		printf("input file error\n");
		printf("usage:./a.out srcfile destfile\n");
		return -1;
	}

	//定义变量获取源文件的长度
	int len=get_file_len(argv[1],argv[2]);

	//定义结构体并初始化
	SI *file=(SI *)malloc(sizeof(struct Info));
	file->length=len;
	file->src=argv[1];
	file->dest=argv[2];

	//定义两个线程号变量
	pthread_t tid1,tid2;

	//创建线程
	if(pthread_create(&tid1,NULL,task1,file)!=0)
	{
		perror("tid1 create error\n");
		return -1;
	}
	if(pthread_create(&tid2,NULL,task2,file)!=0)
	{
		perror("tid2 create error\n");
		return -1;
	}

	//回收资源
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);

	//释放结构体内存
	free(file);
	file=NULL;

	return 0;
}

//定义获取文件长度的函数
int get_file_len(const char *srcfile,const char *destfile)
{
	//以只读的形式打开源文件
	int srcfd,destfd;
	if((srcfd=open(srcfile,O_RDONLY))==-1)
	{
		perror("srcfile open error\n");
		return -1;
	}
	//以只写和创建的形式打开目标文件
	if((destfd=open(destfile,O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
	{
		perror("destfile open error\n");
		return -1;
	}

	//求源文件的大小
	int len=lseek(srcfd,0,SEEK_END);

	//关闭两个文件
	close(srcfd);
	close(destfd);

	return len;
}

//定义文件拷贝函数
int copy_file(const char *srcfile,const char *destfile,int start,int len)
{
	int srcfd,destfd;
	//以只读的形式打开源文件,以读写的形式打开目标文件
	if((srcfd=open(srcfile,O_RDONLY))==-1)
	{
		perror("srcfile open error\n");
		return -1;
	}
	if((destfd=open(destfile,O_RDWR))==-1)
	{
		perror("destfile open error\n");
		return -1;
	}

	//移动文件的光标
	lseek(srcfd,start,SEEK_SET);
	lseek(destfd,start,SEEK_SET);

	//完成拷贝工作
	char buf[128]="";//定义搬运工
	int sum=0;//用于累计搬运的大小
	while(1)
	{
		int res=read(srcfd,buf,sizeof(buf));
		sum+=res;//将每次读取的数据放入到sum中
		if(sum>=len||res==0)
		{
			write(destfd,buf,res-(sum-len));//将最后一次搬运的内容写入
			break;
		}

		//将读取的数据写入目标文件
		write(destfd,buf,res);
	}

	//关闭文件
	close(srcfd);
	close(destfd);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/410364.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

input输入框过滤非金额内容保留一个小数点和2位小数

这篇是输入框过滤非金额内容保留一个小数点和2位小数&#xff0c;金额的其他格式化可以看这篇文章常用的金额数字的格式化方法 js方法直接使用 该方式可以直接使用过滤内容&#xff0c;也可以到onInput或onblur等地方过滤&#xff0c;自行使用 /*** 非金额字符格式化处理* p…

有趣的CSS - 弹跳的圆

大家好&#xff0c;我是 Just&#xff0c;这里是「设计师工作日常」&#xff0c;今天分享的是用css写一个好玩的不停弹跳变形的圆。 《有趣的css》系列最新实例通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样式页…

解读2024生物发酵展览会-蓝帕控制阀门

参展企业介绍 感谢你正在或即将使用LAPAR系列产品&#xff0c;感谢你关注LAPAR&#xff01; LAPAR&#xff0c;流体控制领域的国际品牌之一&#xff0c;总部位于意大利米兰&#xff0c;成立多年以来&#xff0c;LAPAR凭借其完善的网络体系、优秀的产品质量、一体式的客户解决…

蓝桥杯-成绩分析

许久不敲代码&#xff0c;库名也忘了&#xff0c;精度设置还有求最大最小值都是常规题了。 #include <iostream> #include <iomanip> using namespace std; int main() { //一种不用开数组的方法 int n; cin>>n; int top0; int low100;//确定最大…

Uva 101: 木块问题(The Blocks Problem)

看着算法书看到了这一题&#xff0c;想着不能只看不做&#xff0c;就想着做了一下 算法书上的描述太抽象了&#xff0c;就网上找了其他的描述 当然去看英文描述是最准确的&#xff0c;算法书上说是哪一个oj网来着&#xff1f;我给忘了 STL还是很好用的 代码如下&#xff1a; …

【Vue3】学习watch监视:深入了解Vue3响应式系统的核心功能(下)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

【Android12】Monkey压力测试源码执行流程分析

Monkey压力测试源码执行流程分析 Monkey是Android提供的用于应用程序自动化测试、压力测试的测试工具。 其源码路径(Android12)位于 /development/cmds/monkey/部署形式为Java Binary # development/cmds/monkey/Android.bp // Copyright 2008 The Android Open Source Proj…

Windows 安装Redis(图文详解)

一、Redis是什么数据库&#xff1f; Remote Dictionary Server(Redis) 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库&#xff0c;并提供多种语言的 API&#xff0c;是跨平台的非关系型数据库。 …

多线程和并发

线程 进程&#xff1a;在操作系统中运行的程序&#xff0c;一个进程可以包含多个线程 程序就是指令和数据的有序集合&#xff0c;静态概念 进程就是执行程序的一次执行过程&#xff0c;动态概念系统资源分配的单元 一个进程中包含多个线程&#xff0c;一个进程至少包含一个线…

图解KMP算法

目录 1.最长公共前后缀1.1前缀1.2后缀1.3最长公共前后缀 2、KMP算法过程2.1例子12.2例子22.3Python代码&#xff1a;2.4next数组的计算过程 1.最长公共前后缀 1.1前缀 前缀说的是一个字符串除了最后一个字符以外&#xff0c;所有的子串都算是前缀。 前缀字符串&#xff1a;A…

KubeSphere实战

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 知…

49.仿简道云公式函数实战-文本函数-Ip

1. Ip函数 获取当前用户的ip地址 注意是Ipv4的地址 2. 函数用法 IP() 3. 函数示例 获取当前用户的ip地址IP() 4. 代码实战 首先我们在function包下创建text包&#xff0c;在text包下创建IpFunction类&#xff0c;代码如下&#xff1a; package com.ql.util.express.sel…

11:日志分析系统ELK|Elasticsearch|kibana

日志分析系统ELK&#xff5c;Elasticsearch&#xff5c;kibana 日志分析系统ELKELK概述Elasticsearch安装Elasticsearch部署Elasticsearch集群Elasticsearch插件 熟悉Elasticsearch的API调用_cat API创建 tedu 索引使用 PUT 方式增加数据查询数据修改数据删除数据 KibanaKibana…

(挖坑) Python调用图工具

基本效果 输入 #!/usr/bin/env pythonThis example demonstrates a simple use of pycallgraph.from pycallgraph import PyCallGraph from pycallgraph.output import GraphvizOutputclass Banana:def eat(self):passclass Person:def __init__(self):self.no_bananas()def…

Xcode与Swift开发小记

引子 鉴于React Native目前版本在iOS上开发遇到诸多问题&#xff0c;本以为搞RN只需理会Javascript开发&#xff0c;没想到冒出CocoaPod的一堆编译问题。所以横下一条心&#xff0c;决定直接进攻iOS本身。不管你是用React Native&#xff0c;还是用Flutter&#xff0c;iOS下的…

算能RISC-V通用云开发空间编译pytorch @openKylin留档

终于可以体验下risc-v了&#xff01; 操作系统是openKylin&#xff0c;算能的云空间 尝试编译安装pytorch 首先安装git apt install git 然后下载pytorch和算能cpu的库&#xff1a; git clone https://github.com/sophgo/cpuinfo.git git clone https://github.com/pytorc…

java农产品商城商城计算机毕业设计包运行调试讲解

jsp mysql农业商城 特效&#xff1a;js产品轮播 功能&#xff1a; 前台&#xff1a; 1.绿色水果 图文列表 详情 2.新闻动态 文章标题列表 详情 3.有机蔬菜 图文列表 详情 4.有机谷物 图文列表 详情 5.有机大米 图文列表 详情 6.用户注册 登陆&#xff08;选择用户和管…

c++ 广度优先搜索(Breadth-First Search,BFS)

广度优先搜索&#xff08;Breadth-First Search&#xff0c;BFS&#xff09;是一种图遍历算法&#xff0c;通常用于搜索或遍历树和图等数据结构。其基本思想是先访问起始顶点&#xff0c;然后逐层遍历其相邻的顶点&#xff0c;直到找到目标顶点或遍历完所有顶点。 BFS通常使用…

前端基础面试题(一)

摘要&#xff1a;最近&#xff0c;看了下慕课2周刷完n道面试题&#xff0c;记录下... 1.请说明Ajax、Fetch、Axios三者的区别 三者都用于网络请求&#xff0c;但维度不同&#xff1a; Ajax&#xff08;Asynchronous Javascript ang XML&#xff09;&#xff0c;是一种在不重新…

xss-跨站脚本攻击漏洞

前备知识&#xff1a; Cookie和Session是Web开发中用于维持用户状态、跟踪用户会话的核心技术&#xff0c;它们的主要目的是在无状态的HTTP协议基础上实现有状态的用户交互。 **Cookie**&#xff1a; - Cookie是一种由服务器发送到客户端&#xff08;通常是用户的浏览器&#x…