Linux进程

进程

进程概念

**1. 什么是程序,什么是进程,有什么区别

  • 程序是静态的概念,gcc xx.c-pro 磁盘中生成pro文件,叫做程序
  • 进程是程序的一次运行活动,通俗点就是程序跑起来,系统中多了一个进程,动态
  1. 如何查看系统中有哪些进程
  • Linux命令行输指令 ps是进程,完整的是ps -aux显示
  • 实际工作中,配合grep 来查找程序中是否存在某一个进程 比如 ps-aux|grep init - 进程
  • 类似Window下ctrl+alt+delat,在Linux指令输入top
  1. 什么是进程标识符
  • 每个进程都有一个非负整数表示唯一ID,叫做pid
  • pid = 0,称为交换进程(swapper)
  • pid = 1;init进程,作用系统初始化
  • 在Linux指令输入man getpid获得进程ID号
    输入man 2 getpid
#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);
pid_t getppid(void);
#include <sys/types.h>
#include <unistd.h>

int main()
{
	pid_t pid;
	pid = getpid();

	printf("my getpid is %d\n",pid);
	while(1);//不让程序退出
	return 0;
}

输出结果:my getpid is 4310
Linux命令行top,查看进程,发现这个4310CPU占用率1000%,因为while(1)一直在运行。

  • 什么叫父进程,什么叫子进程
  • 父进程与子进程
  • C程序的存储空间是如何分配内存
    在这里插入图片描述
    具体文章C程序内存分配
    可执行程序包括BSS段、数据段、代码段。
    《UNIX高级编程》重要的一本书
    比如malloc申请的空间是在堆里面,函数调用(局部变量)一般在栈里面。
  • BSS段,数据初始化为0或空指针。
  • 堆,动态存储空间。
  • 栈,函数调用(局部变量)等。

进程创建

创建一个进程

pid_t fork(void);

fork函数调用成功,返回两次

  • 返回值为0,代表当前进程是子进程
  • 返回值非负数,代表当前进程为父进程
  • 调用失败,返回-1
#include <sys/types.h>
#include <unistd.h>

int main()
{
	pid_t pid;
	pid = getpid();
	fork();

	printf("my getpid is %d\n",pid);
	
	return 0;
}

输出结果:my getpid is 5187
my getpid is 5187
为什么会有两个呢

下面为测试

#include <sys/types.h>
#include <unistd.h>

int main()
{
	pid_t pid;
	pid = getpid();
	fork();

	printf("my getpid is %d,current pro id :%d \n",pid,geipid());
	
	return 0;
}

输出结果:my getpid is 5274,current pro id :5274
my getpid is 5274,current pro id :5275

#include <sys/types.h>
#include <unistd.h>

int main()
{
	pid_t pid;
	pid = getpid();
	fork();

	if(pid == getpid())
	{
		printf("this is father printf\n");
	}else{
		printf("this is child print, child id=%d\n",getpid());
	}
	
	
	return 0;
}

输出结果:this is father printf
this is child print, child id = 5364

下面这个测试结果重要

#include <sys/types.h>
#include <unistd.h>

int main()
{
	pid_t pid;
	pid_t pid2;
	pid = getpid();
	printf("before fork:pid = %d\n",pid);
	
	fork();
	
	pid2 = getpid();
	printf("after fork:pid = %d\n",pid2);

	if(pid == pid2 )
	{
		printf("this is father printf\n");
	}else{
		printf("this is child print, child id=%d\n",getpid());
	}
	
	
	return 0;
}

输出结果:before fork:pid = 5384
after fork:pid = 5384
this is father printf
after fork:pid = 5385
this is child print, child id = 5385

#include <sys/types.h>
#include <unistd.h>

int main()
{
	pid_t pid;

	printf("father id is:%d\n",getpid());
	
	pid = fork();

	if(pid > 0 )
	{
		printf("this is father printf,pid = %d\n",getpid());
	}else(pid == 0){
		printf("this is child print, child id=%d\n",getpid());
	}
	
	
	return 0;
}

输出结果:father id is:5541
this is father printf,pid = 5541
this is child print, child id= 5542
上面测试结果,pid>0是父进程,子进程是pid==0

#include <sys/types.h>
#include <unistd.h>

int main()
{
	pid_t pid;
	pid_t pid2;
	pid_t retpid;

	pid = getpid();
	printf("before fork:pid = %d\n",pid);
	
	retpid = fork();
	
	pid2 = getpid();
	printf("after fork:pid = %d\n",pid2);

	if(pid == pid2 )
	{
		printf("this is father printf  retpid :%d\n",retpid);
	}else{
		printf("this is child print, retpid :%d,child id=%d\n",retpid,getpid());
	}
	
	
	return 0;
}

输出结果:before fork:pid = 5794
father id is:5794
this is father printf, retpid= 5795
this is child print, retpid :0,child id=5795
这个测试结果,发现pid>0的值是子进程的 id号,retpid
然后fork以后会拷贝一份id号给子进程retpid,然后给retpid赋值为0

进程创建发生了什么

父进程与子进程之间会拷贝
上面会共享内存

验证

#include <sys/types.h>
#include <unistd.h>

int main()
{
	pid_t pid;
	int data = 10;

	printf("father id is:%d\n",getpid());
	
	pid = fork();

	if(pid > 0 )
	{
		printf("this is father printf,pid = %d\n",getpid());
	}else(pid == 0){
		printf("this is child print, child id=%d\n",getpid());
	}
	printf("data : %d\n",data);
	
	return 0;
}

输出结果:father id is:6239
this is father printf,pid = 6239
data : 10
this is child print, child id= 6240
data : 10

#include <sys/types.h>
#include <unistd.h>

int main()
{
	pid_t pid;
	int data = 10;

	printf("father id is:%d\n",getpid());
	
	pid = fork();

	if(pid > 0 )
	{
		printf("this is father printf,pid = %d\n",getpid());
	}else if(pid == 0){
		printf("this is child print, child id=%d\n",getpid());
		data = data + 100;
	}
	printf("data : %d\n",data);
	
	return 0;
}

输出结果:father id is:6264
this is father printf,pid = 6264
data : 10
this is child print, child id= 6265
data : 110

创建子进程为什么

  • 1、一个父进程希望复制自己,使父、子进程同时执行不同的代码段。这在网络服务进程中是常见的——父进程等待客户端的服务请求。当这种请求到达时,父进程调用fork,使子 进程处理此请求。父进程则继续等待下一个服务请求到达。
  • 2、 一个进程要执行一个不同的程序。这对shell是常见的情况。在这种情况下,子进程从
    fork返回后立即调用exec(我们将在8.10节说明exec)。

在这里插入图片描述

#include <sys/types.h>
#include <unistd.h>

int main()
{
	pid_t pid;
	int data = 10;

	while(1){
		printf("please input a data\n");
		scanf("%d",&data);
		if(data == 1){
			pid = fork();

			if(pid > 0 )
			{
			
			}
			else if(pid == 0){
				while(1){
					printf("do net request pid = %d\n",getpid());
					sleep(1);
				}
			}else{
				printf("wait do nothing\n");
			}
				
		}

	}
	
	
	return 0;
}

输出结果:1
do net request pid = 6917
do net request pid = 6918
do net request pid = 6917
do net request pid = 6918
在输入:1
do net request pid = 6919
do net request pid = 6920
do net request pid = 6919
do net request pid = 6920

在这里插入图片描述

vfork与fork区别

vfork函数也可以创建进程,与fork有什么区别

区别一:vfork直接使用父进程存储空间,不拷贝。
区别二:vfork保证子进程先运行,当子进程调用exit退出后,父进程才执行。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

int main()
{
	pid_t pid;
	int cnt = 0;
	
	pid = vfork();

	if(pid > 0 )
	{
		while(1){
			printf("cnt = %d\n",cnt);
			printf("this is father printf,pid = %d\n",getpid());
			sleep(1);
		}
		
	}else if(pid == 0){
			while(1){
				printf("this is child print, child id=%d\n",getpid());
				sleep(1);
				cnt++;
				if(cnt == 3){
					exit(0);
				}
			}
		
	}
	return 0;
}

fork的话,子进程与父进程几乎同时在执行
而如果是vfork,子进程先进行

输出结果:this is child print, child id=7239
this is child print, child id=7239
this is child print, child id=7239
cnt = 3
this is father printf,pid = 7238
cnt = 3
this is father printf,pid = 7238
cnt = 3
this is father printf,pid = 7238

进程退出

正常退出

  • Main函数调用return
  • 进程调用exit(),标准C库
  • 进程调用_exit()或者_Exit(),属于系统调用

补充

  • 进程最后一个线程返回
  • 最后一个线程调用pthread_exit

异常退出

  • 调用abort
  • 当进程收到某些信号时,如ctrl+c
  • 最后一个线程对曲线(cancellation)请求做出响应

父进程等待子进程退出(wait)

为什么要等待子进程退出
创建子进程目的->做东西

父进程等待子进程退出并收集子进程的退出状态
子进程退出状态不被收集,变成僵尸进程

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

int main()
{
	pid_t pid;
	int cnt = 0;
	
	pid = fork();

	if(pid > 0 )
	{
		wait(NULL);
		while(1){
			printf("cnt = %d\n",cnt);
			printf("this is father printf,pid = %d\n",getpid());
			sleep(1);
		}
		
	}else if(pid == 0){
			while(1){
				printf("cnt = %d\n",cnt);
				printf("this is child print, child id=%d\n",getpid());
				sleep(1);
				cnt++;
				if(cnt == 5){
					exit(0);
				}
			}
		
	}
	return 0;
}

上面会出现僵尸进程
运行./newpro
输出结果:this is child print, child id=9362
this is child print, child id=9362
this is child print, child id=9362
cnt = 3
this is father printf,pid = 9363
cnt = 3
this is father printf,pid = 9363
cnt = 3
this is father printf,pid = 9363
在Linux命令行输入 ps -aux |grep newpro
Z+就是僵尸进程,S+就是在运行

运用wait函数
STATUS参数:是一个整形指数指针
非空:子进程退出状态放在它所指向的地址中
空:不关系退出状态

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status);
pid_t waitpid(pid_t pid,int *status,int options);
int waitid(idtype_t idtype,id_t id,siginfo_t *infop,int options);

下面是不关系退出状态

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

int main()
{
	pid_t pid;
	int cnt = 0;
	
	pid = fork();

	if(pid > 0 )
	{
		while(1){
			printf("this is father printf,pid = %d\n",getpid());
			sleep(1);
		}
		
	}else if(pid == 0){
			while(1){
				printf("cnt = %d\n",cnt);
				printf("cnt = %d\n",cnt);
				printf("this is child print, child id=%d\n",getpid());
				sleep(1);
				cnt++;
				if(cnt == 3){
					exit(0);
				}
			}
		
	}
	return 0;
}

输出结果:this is child print, child id=9495
this is child print, child id=9495
this is child print, child id=9495
cnt = 0
this is father printf,pid = 9494
cnt = 0
this is father printf,pid = 9494
cnt = 0
this is father printf,pid = 9494
在Linux命令行输入 ps -aux |grep newpro
9495这个进程被回收了

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

int main()
{
	pid_t pid;
	int cnt = 0;
	int status = 10;

	
	pid = fork();

	if(pid > 0 )
	{
		wait(&status);
		printf("chiled quit,child status = %d\n",status);
		while(1){
			printf("cnt = %d\n",cnt);
			printf("this is father printf,pid = %d\n",getpid());
			sleep(1);
		}
		
	}else if(pid == 0){
			while(1){
				printf("cnt = %d\n",cnt);
				printf("this is child print, child id=%d\n",getpid());
				sleep(1);
				cnt++;
				if(cnt == 3){
					exit(3);//假设是3
				}
			}
		
	}
	return 0;
}

输出结果:this is child print, child id=9550
this is child print, child id=9550
this is child print, child id=9550
this is child print, child id=9550
this is child print, child id=9550
chiled quit,child status = 768
cnt = 0
this is father printf,pid = 9549
cnt = 0
this is father printf,pid = 9549
cnt = 0
this is father printf,pid = 9549
这里出现status怪怪的

在这里插入图片描述

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

int main()
{
	pid_t pid;
	int cnt = 0;
	int status = 10;

	
	pid = fork();

	if(pid > 0 )
	{
		wait(&status);
		printf("chiled quit,child status = %d\n",WEITSTATUS(status));//检测退出码 
		while(1){
			printf("cnt = %d\n",cnt);
			printf("this is father printf,pid = %d\n",getpid());
			sleep(1);
		}
		
	}else if(pid == 0){
			while(1){
				printf("cnt = %d\n",cnt);
				printf("this is child print, child id=%d\n",getpid());
				sleep(1);
				cnt++;
				if(cnt == 3){
					exit(3);//假设是3
				}
			}
		
	}
	return 0;
}

输出结果:this is child print, child id=9590
this is child print, child id=9590
this is child print, child id=9590
this is child print, child id=9590
this is child print, child id=9590
chiled quit,child status = 3
cnt = 0
this is father printf,pid = 9589
cnt = 0
this is father printf,pid = 9589
cnt = 0
this is father printf,pid = 9589
这次输出对的了,退出状态码是3

wait与waitpid区别

  • 如果其所有子进程都还在运行,则阻塞
  • 如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回
  • 如果它没有任何子进程,则立即出错返回

wait使调用者阻塞,waitpid有一个选项,可以使调用者不阻塞

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

int main()
{
	pid_t pid;
	int cnt = 0;
	int status = 10;

	
	pid = fork();

	if(pid > 0 )
	{
		watipid(pid,&status,WNOHANG);
		printf("chiled quit,child status = %d\n",WEITSTATUS(status));//检测退出码 
		while(1){
			printf("cnt = %d\n",cnt);
			printf("this is father printf,pid = %d\n",getpid());
			sleep(1);
		}
		
	}else if(pid == 0){
			while(1){
				printf("cnt = %d\n",cnt);
				printf("this is child print, child id=%d\n",getpid());
				sleep(1);
				cnt++;
				if(cnt == 3){
					exit(3);//假设是3
				}
			}
		
	}
	return 0;
}

waitpid这个不关心子进程状态,父子进程一起运行

孤儿进程

  • 父进程如果不等待子进程退出,在自称金之前就结束了自己的生命,此时子进程叫做孤儿进程
  • Linux避免系统存在过多孤儿进程,init进程收留孤儿进程,变成孤儿进程的父进程
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

int main()
{
	pid_t pid;
	int cnt = 0;
	int status = 10;

	
	pid = fork();

	if(pid > 0 )
	{
		printf("this is father printf,pid = %d\n",getpid());
	}
		
	}else if(pid == 0){
			while(1){
				printf("cnt = %d\n",cnt);
				printf("this is child print, child id=%d father id =%d\n",getpid(),getppid());
				sleep(1);
				cnt++;
				if(cnt == 3){
					exit(3);//假设是3
				}
			}
		
	}
	return 0;
}

输出结果:
this is father printf,pid = 9853
"this is child print, child id=9854 father id =9853
this is child print, child id=9854,father id =1
this is child print, child id=9854 father id =1
this is child print, child id=9854 father id =1
this is child print, child id=9854 father id =1
Linux命令行ps -aux|grep newpro

看《UNIX高级编程》的demo

exec族函数

Excel族函数
https://blog.csdn.net/u014530704/article/details/73848573
**运用exec组函数的原因:**一个进程要执行一个不同的程序。这对shell是常见的情况。在这种情况下,子进程从
fork返回后立即调用exec(我们将在8.10节说明exec)。

#include <stdio.h>

int main(int argc,char *argv[])
{
	int i =0;
	for(i=0;i<argc;i++)
	{
		printf("argc[%d] :%s\n",i,argv[i]);
	}

	return 0;
}

Linux命令行./a.out file1 file2
输出结果:
argv[0] :./a.out
argv[1]: file1
argv[2]: file2

//文件execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("before execl\n");
    if(execl("./bin/echoarg","echoarg","abc",NULL) == -1)
    {
        printf("execl failed!\n");    
         
        perror("why"); 
    }
    printf("after execl\n");
    return 0;
}

输出结果:
before execl
execl failed
why:NO such file or directory
after execl

//文件execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("before execl\n");
    if(execl("./echoarg","echoarg","abc",NULL) == -1)
    {
        printf("execl failed!\n");    
         
        perror("why"); 
    }
    printf("after execl\n");
    return 0;
}

输出结果:
before execl
argv[0] :.echarg
argv[1]: abc

实验说明:
我们先用gcc编译echoarg.c,生成可执行文件echoarg并放在当前路径bin目录下。文件echoarg的作用是打印命令行参数。然后再编译execl.c并执行execl可执行文件。用execl 找到并执行echoarg,将当前进程main替换掉,所以”after execl” 没有在终端被打印出来。
————————————————
版权声明:本文为CSDN博主「云英」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u014530704/article/details/73848573

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("before execl\n");
    if(execl("/bin/ls","ls",NULL,NULL) == -1)
    {
        printf("execl failed!\n");    
         
        perror("why"); 
    }
    printf("after execl\n");
    return 0;
}

输出结果:before execl
然后就使Linux命令行ls

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("before execl\n");
    if(execl("/bin/ls","ls","-l",NULL) == -1)
    {
        printf("execl failed!\n");    
         
        perror("why"); 
    }
    printf("after execl\n");
    return 0;
}

输出结果:before execl
然后就像Linux命令行ls-l

Linux命令行data,获取时间

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("before execl\n");
    if(execl("/bin/data","data",NULL,NULL) == -1)
    {
        printf("execl failed!\n");    
         
        perror("why"); 
    }
    printf("after execl\n");
    return 0;
}

输出结果跟Linux命令行data,获取时间一样

execlp

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("before execl\n");
    if(execlp("data","data",NULL,NULL) == -1)//
    {
        printf("execl failed!\n");    
         
        perror("why"); 
    }
    printf("after execl\n");
    return 0;
}

echo &path目标文件夹在哪里
pwd显示当前文件
环境变量
echo &path把目标文件在环境变量执行

execvp

//文件execvp.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execvp(const char *file, char *const argv[]);

int main(void)
{
    printf("before execlp****\n");
    char *argv[] = {"ps","-l",NULL};
    if(execvp("ps",argv) == -1) 
    {
        printf("execvp failed!\n");     
    }
    printf("after execlp*****\n");
    return 0;
}

执行结果

ubuntu:~/test/exec_test$ gcc execvp.c -o execvp
ubuntu:~/test/exec_test$ ./execvp
before execlp****
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 R 1048 63491 74920 0 80 0 - 2860 - pts/4 00:00:00 ps
0 S 1048 74920 74916 0 80 0 - 7579 wait pts/4 00:00:00 bash

exec配合fork使用

实现功能,当父进程检测到输入为1的时候,创建子进程把配置文件的字段值修改掉

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

int main()
{
	pid_t pid;
	int data = 10;

	while(1){
		printf("please input a data\n");
		scanf("%d",&data);
		if(data == 1){
			int fdSrc;
			pid = fork();
			
			if(pid == 0){
				int fdSrc;

				char *readBuf = NULL;

				fdSrc = open("config.txt",O_RDWR);
				int size = lseek(fdSrc,0,SEEK_END);
				lseek(fdSrc,0,SEEK_SET);

				readBuf = (char *)malloc(sizeof(char)*size + 8);

				int n_read = read(fdSrc,readBuf,size);
				/*改目标值*/
				char *p = strstr(readBuf,"LENG = ");
				if(p == NULL){
					printf("not found\n");
					exit(-1);
				}

				p = p + strlen("LENG =");
				*p = 5;
				/*************************/
				lseek(fdSrc,0,SEEK_SET);
				int n_write = write(fdSrc,readBuf,strlen(readBuf));
				close(fdSrc);
			}
			else{
				printf("wait , do nothing\n");
			}
				
				
		}

	}
	
	
	return 0;
}

Linux命令行
cp…/FILE/
cp…/FILE/TEST.config config.txt
cat config.txt //观看文档的值

输出结果:当输入1,将文件夹的值“LENG = 5”

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

int main()
{
	pid_t pid;
	int data = 10;

	while(1){
		printf("please input a data\n");
		scanf("%d",&data);
		if(data == 1){
			int fdSrc;
			
			pid = fork();
			if(pid > 0)
			{
				wait(NULL);
			}
			else if(pid == 0){
				execl("./changData","changData","config.txt",NULL);
				exit(0);
			}
			else{
				printf("wait , do nothing\n");
			}
				
				
		}

	}
	
	
	return 0;
}

之前生成了changData这个文件,execl将这个文件读取到config.txt这个文件

system函数

man system

#include <stdlib.h>

int system(const char *command);

system()函数的返回值如下:成功,则返回进程的状态值,当sh不能执行时,返回127;失败返回-1。

执行方式./11这种方式,还有sh -c ./11这种
https://www.cnblogs.com/leijiangtao/p/4051387.html,system原函数文章

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

int main()
{
	pid_t pid;
	int data = 10;

	while(1){
		printf("please input a data\n");
		scanf("%d",&data);
		if(data == 1){
			int fdSrc;
			
			pid = fork();
			if(pid > 0)
			{
				wait(NULL);
			}
			else if(pid == 0){
				system("./changData config.txt");
				exit(0);
			}
			else{
				printf("wait , do nothing\n");
			}
				
				
		}

	}
	
	
	return 0;
}

cat config.txt
输出结果:将文件夹的值“LENG = 5”

system与execl区别就是,system还会执行后面的代码,execl成功执行不会执行后面代码

popen函数

比system在应用中的好处:可以获取运行的输出结果

#inlcude <stdio.h>

FILE *popen(const char *command,const char *type);
int pclose(FILE *stream);

https://blog.csdn.net/libinbin_1014/article/details/51490568
system

#include <stdio.h>
#include <string.h>
int main(void)
{
    char ret[1024] = {0};

	system("ps");

	printf("res :%s\n",,ret);

    return 0;
}

输出结果就是,会执行PS
system后面不会在输出了,
popen

#include <stdio.h>
#include <string.h>
int main(void)
{
    char ret[1024] = {0};
	FILE *fp;

	fp = popen("ps","r");
	int n_read = fread(ret,1,1024,fp);

	printf("read ret %d byte,res :%s\n",,n_read,ret);

    return 0;
}

输出结果:read ret 357byte ret = PID TTY


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值