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

news2025/1/15 13:14:30

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);
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode_Java_环形链表(题目+思路+代码)

141.环形链表 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位…

springboot项目打成含crud操作的sdk集成到springboot启动引擎项目

一 sdk配置操作 1.1 结构 sdk项目目录中只有基础的service类以及mybatis操作数据库的相关文件&#xff0c;service类中包含查询数据库的方法。 说明&#xff1a; 1.2 sdk的pom打包配置 作为公共项目打成jar供其他项目引用&#xff0c;注意被引入的项目不能使用默认的maven…

python 运算符总结

什么是运算符 什么是运算符? 先看如下示例 549 例子中&#xff0c;4 和 5 被称为操作数&#xff0c; 称为运算符。 而Python 语言支持以下类型的运算符: 算术运算符比较&#xff08;关系&#xff09;运算符赋值运算符逻辑运算符位运算符成员运算符身份运算符运算符优先级 …

UDP 与 TCP 的区别是什么?

目录 区别 一、面向无连接 二、不可靠性 三、高效 四、传输方式 五、适用场景 1.直播 2.英雄联盟 六、总结 区别 首先 UDP 协议是面向无连接的&#xff0c;也就是说不需要在正式传递数据之前先连接起双方。然后 UDP 协议只是数据报文的搬运工&#xff0c;不保证有序且…

第十二天-邮件发送

目录 发送邮件的流程 邮件的发送协议 smtplib模块 email包 demo 发送html邮箱 发送带附件的邮箱 发送定时邮件schedule模块 发送邮件的流程 邮件的发送协议 smtp是邮件的发送协议pop3是邮件的接受协议协议就是一种规则&#xff0c;已经被底层网络封装好了&#xff0c;无…

第三节:Vben Admin登录对接后端login接口

系列文章目录 第一节&#xff1a;Vben Admin介绍和初次运行 第二节&#xff1a;Vben Admin 登录逻辑梳理和对接后端准备 文章目录 系列文章目录前言一、Flask项目介绍二、使用步骤1.User模型创建2.迁移模型3. Token创建4. 编写蓝图5. 注册蓝图 三. 测试登录总结 前言 上一节&…

【零基础】VOSviewer小白入门第一课

官网安装&#xff1a;VOSviewer - Visualizing scientific landscapes 安装完成后即可以打开VOSviewer: 在 wos of science 中搜索关键词&#xff1a;lawdata 选择导出&#xff0c;按照plain text file格式导出&#xff0c;可以到处1000个。选择all record 得到下图 读取vosvi…

zabbix监控业务数据

前言 监控系统除了监控os和数据库性能相关的指标外&#xff0c;业务数据也是重点监控的对象。 一线驻场的运维同学应该深有体会&#xff0c;每天需要向甲方或者公司反馈现场的数据情况&#xff0c;正常情况下一天巡检两次&#xff0c;早上上班后和下午下班前各一次。监控项目…

JWT学习笔记

了解 JWT Token 释义及使用 | Authing 文档 JSON Web Token Introduction - jwt.io JSON Web Token (JWT&#xff0c;RFC 7519 (opens new window))&#xff0c;是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准&#xff08;(RFC 7519)。该 token 被设计为紧凑…

国家能源、华能、一汽、中国交建、中国铁塔、中国烟草、中航信托--校园招聘历年题库和真题

作为准备参加国有企业校园招聘的应聘者&#xff0c;掌握相关企业的招聘试题资料是至关重要的。国家能源、华能、一汽、中国交建、中国铁塔、中国烟草、中航信托等知名国有企业在中国经济中扮演着重要的角色&#xff0c;每年都会举行校园招聘活动&#xff0c;吸引大批毕业生和应…

【项目部署上线】宝塔部署前端Docker部署后端

【项目部署上线】宝塔部署前端&Docker部署后端 文章目录 【项目部署上线】宝塔部署前端&Docker部署后端1.安装依赖1.1 安装mysql1.2 安装Canal1.3 安装redis1.4 安装rabbitmq1.5 安装nacos 2. 部署前端3. 部署后端 1.安装依赖 1.1 安装mysql docker run -d -p 3306:3…

面向面试的机器学习知识点(4)——分类模型

省流版&#xff1a; 本文介绍机器学习中的回归算法&#xff1a;逻辑回归、KNN、SVM、随机森林和XGBoost。作为机器学习的有监督学习方法&#xff0c;分类模型是最重要也是最常见的一类算法&#xff0c;在数据分析等岗位的笔试面试中都是常客&#xff0c;非常值得深入研究&…

基于Prony算法的系统参数辨识matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 Prony算法是一种用于信号处理和系统辨识的经典方法&#xff0c;特别适用于线性时不变系统&#xff08;LTI&#xff09;的频率响应分析以及模拟复指数信号序列。其…

特殊文件:XML文件,Properties属性文件【详解】

目录 1.Properties属性文件 2.特殊文件&#xff1a;XML文件 1.Properties属性文件 是一个Map集合&#xff08;键值对集合&#xff09;&#xff0c;但是我们一般不会当集合使用。 核心作用&#xff1a;Properties是用来代表属性文件的&#xff0c;通过Properties可以读写…

【MySQL】学习和总结联合查询

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-OPj5g6evbkm5ol0U {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

FPGA 与 数字电路的关系 - 这篇文章 将 持续 更新 :)

先说几个逻辑&#xff1a;&#xff08;强调一下在这篇文章 输入路数 只有 1个或2个&#xff0c;输出只有1个&#xff0c;N个输入M个输出以后再说&#xff09; 看下面的几个图&#xff1a; 图一&#xff08; 忘了 这是 啥门&#xff0c;不是门吧 &#xff1a;&#xff09;也就…

UE5 C++ TPS开发 学习记录(五)

这节课创建了新的游戏关卡Lobby,制作了属于自己的游戏名字"Match Type",制作了加入游戏会话的委托和函数,最后可以用IP就可以把客户端链接到服务端 .h // Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #incl…

pytest如何在类的方法之间共享变量?

在pytest中&#xff0c;setup_class是一个特殊的方法&#xff0c;它用于在类级别的测试开始之前设置一些初始化的状态。这个方法会在类中的任何测试方法执行之前只运行一次。 当你在setup_class中使用self来修改类属性时&#xff0c;你实际上是在修改类的一个实例属性。在Pyth…

高频面试题整理(二)

文章目录 索引相关问题优化你的索引 密集索引和稀疏索引如何定位并优化慢查询sqlMyISAM与InnoDB 关于锁方面的区别是什么&#xff1f;MyISAMInnoDB事务隔离级别 多线程并发的相关问题Thread中的start和run方法的区别Thread和Runnable是什么关系&#xff1f;如何处理线程的返回值…

【Java程序设计】【C00307】基于Springboot的基Hadoop的物品租赁管理系统(有论文)

基于Springboot的基Hadoop的物品租赁管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的基于 Hadoop的物品租赁系统的设计与实现&#xff0c;本系统有管理员、用户二种角色权限&#xff1b; 前台首页&#…