2024.12.12(进程续)

9、作业:创建3个进程,子进1程拷贝文件的前一半,子进程2拷贝后一半文件,父进程回收两个子进程资源。

#include <myhead.h>
int main(int argc, const char *argv[])
{
	int fd1,fd2,fd3;
	pid_t pid1 = fork();
	if(pid1 == 0) 		//子程序1
	{
		fd1 = open("./1.txt",O_RDONLY); 		//只读打开文件
		if(fd1 == -1)
		{
			perror("open");
			return -1;
		}
		fd2 = open("./2.txt",O_CREAT|O_TRUNC|O_WRONLY,0664); //创建只写清空文件
		if(fd2 == -1)
		{
			perror("open");
			return -1;
		}
		//计算长度
		int len = lseek(fd1,0,SEEK_END); 	
		lseek(fd1,0,SEEK_SET); 				//把光标置位到开头
		char buff[1024]; //零时变量
		int res = 0; 	//读取每次的长度
		int len1 = 0; 		//子程序1的取的长度
		while((len1+res)<len/2) 				//循环条件
		{
			res = read(fd1,buff,sizeof(buff)); 	//读取文件
			len1 +=res; 					//累加长度
			write(fd2,buff,res); 			//写入文件2.txt
		}
		//处理剩余部分
		if((len1+res)<len)
		{ 
			res = read(fd1,buff,len/2-len1);
			write(fd2,buff,res);
		}
		printf("子程序1拷贝完成\n");
		close(fd1);
		close(fd2);

	}
	else if(pid1 > 0) 	//父程序
	{
		pid_t pid2 = fork();

		if(pid2 == 0) 	//子程序2
		{
		fd1 = open("./1.txt",O_RDONLY); 		//只读打开文件
		if(fd1 == -1)
		{
			perror("open");
			return -1;
		}
		fd3 = open("./3.txt",O_CREAT|O_TRUNC|O_WRONLY,0664); //创建只写清空文件
		if(fd3 == -1)
		{
			perror("open");
			return -1;
		}
		//计算长度
		int len = lseek(fd1,0,SEEK_END); 	
		lseek(fd1,len/2,SEEK_SET); 				//把光标置位到中间

		char buff[1024]; //临时变量
		int res; 	//读取每次的长度
		int len1 = 0; 		//子程序1的取的长度
		while(res = read(fd1,buff,sizeof(buff))) //读取文件
		{
			write(fd3,buff,res); 			//写入文件3.txt
		}
		printf("子程序2拷贝完成\n");
		close(fd1);
		close(fd3);
		}


		//回收资源
		waitpid(pid1,NULL,0);
		waitpid(pid2,NULL,0);
	}	
	else
	{
		perror("fork");
		return -1;
	}
	return 0;
}

wait和waitpid函数

        #include <sys/types.h>

        #include <sys/wait.h>

                pid_t wait(int *wstatus);

        功能:阻塞回收子进程的资源。

        参数:子进程退出时的状态

        返回值:成功回收子进程资源后返回子进程的ID,失败时返回-1.

                pid_t waitpid(pid_t pid, int *wstatus, int options);

        功能:阻塞或者非阻塞回收子进程资源

        参数1: >0:回收特定某个子进程资源

                =0:回收当前进程组的所有子进程资源

                =-1:回收任意的子进程资源

                <-1:回收进程组ID等于pid绝对值的所有子进程资源.

        参数2:接收进程退出时的状态一般不接收。

        参数3: 0:阻塞回收子进程的资源

                        WNOHANG:非阻塞回收子进程资源.

        返回值:成功返回回收的进程ID,失败返回-1,但是如果参数3是WNOHANG 成功后返回0。

4、验证进程的多任务并发执行

5、验证孤儿进程和僵尸进程

子进程退出后子进程修改的数据是否保存

7、创建守护进程

1、创建一个孤儿进程,并修改孤儿进程的操作目录权限为根目录(对根目录某个文件具有读写权限)。

2、将孤儿进程设置为会话组组长,脱离终端独立运行(该孤儿进程变成守护进程)。

3、更改终端下的umask值,以便于创建的文件具有读写执行的全部权限。

4、在根目录下创建一个日志文件。

5、重定向所有的输入输出出错描述符到该日志文件。

        #include <sys/types.h>

        #include <unistd.h>

                pid_t setsid(void);

        功能:设置调用进程为会话组组长。

        参数:无

        返回值:成功返回会话组组长的(新的)ID失败返回-1,并置位错误码。

        #include <unistd.h>i

                int chdir(const char *path);

        功能:修改调用进程的工作目录。

        参数:要更改的工作目录

        返回值:成功返回0,失败返回-1,并置位错误码。

        #include <sys/types.h>

        #include <sys/stat.h>

                mode_t umask(mode_t mask);

        功能:更改某个目录下的umask值

        参数:要更改的umask值

        返回值:成功返回旧的umask值,没有失败可言。

创建守护进程 

验证如何创建3个进程

线程概念

1、线程是轻量化的进程,一个进程内可以有多个线程,至少包含一个线程(主线程)。

2、线程的任务调度,创建,销毁的开销都要比进程小。

3、进程之间不共享资源,进程运行空间都是独立的,但是线程共享临界资源。

4、线程是任务调度的最小单位,进程是资源分配的最小单位。

5、多任务并发执行大多数选择多线程,而不是多进程,因为线程占用内存非常少大概8K。

6、多个线程每一个都有自己的id号。

7、线程函数来自于第三方库,-pthread,所以要编译线程库函数需要加上 -pthread

8、多线程编程时,对于临界资源访问时可能有多个线程同时访问,这样会产生数据的错乱,这种现象被称为竞态。

pthread_create函数

        #include <pthread.h>

                int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

        功能:创建子线程的函数

        参数1:存储创建的子线程号

        参数2:创建时附加的线程属性,默认填NULL

        参数3:函数指针,子线程的线程体函数,也是子线程开始运行的地方。

        参数4:是线程体函数的参数,如果没有参数填NULL即可。

        返回值:成功返回0,失败返回-1,并且线程号不确定。

思维导图

线程基础

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值