1.程序:可执行文件,可执行指令的集合,是一个文件
2.进程:动态的,运行在内存中,程序执行有一次的过程,伴随着资源的分配和释放;

3.程序的构成
size a.out // size <程序名>
test //代码段
rodate //只读数据段
data //数据段
bss //未初始化的段
4.进程的构成
test //代码段
rodate //只读数据段
data //数据段
bss //未初始化的段
堆、栈、系统相关的信息(命令行参数、环境变量)
5.进程的表示
task_struct 的结构体
6.进程分类:
(1)交互进程;//输入进程
(2)批处理进程//windows 中.bat
(3)守护进程//开机启动,系统关闭而关闭
7.相关命令
pstree //以树型查看当前进程的信息
ps -ef //进程快照,查看当前进程
ps -ef |grep "a.out" //查找"a.out"相关进程
ps -aux |grep "a.out" //查看当前进程号
kill -l // 查看控制进程的信号
//常用宏
SIGKILL 9 杀死进程
SIGCHLD 17 子进程结束时,给父进程发送信号
SIGCONT 18 让信号继续运行
SIGSTOP 19 让信号停止
kill -9 11962

//示例:把一个进程放到后台运行 或者放到前台运行
./a.out //默认前台运行
./a.out & //后台运行
//前台运行一个进程
./a.out
//查看进程号
ps -aux |grep a.out
//停止进程
kill -19 <pid>
//jobs命令查看job号
jobs
//bg
bg 1 //把进程放到后台运行
fg 1 //把进程放到前台运行
//fork()函数创建成功子进程,在子进程中,pid=0,在父进程中pid为子进程的进程号。
(1)创建子进程,子进程把父进程堆区、栈区、可数据区、可读区、系统相关信息复制了一份,并且父子进程互不影响。
(2)fork之后,子进程会继承父进程打开的文件描述符集合,共享文件状态标志位和问价偏移量。
#include
#include
#include
int main(int argc,const char * argv[])
{
pid_t pid;
fork();//创建子进程;
printf("welcom to 22091\n");
while(1);
return 0;
}
//示例:创建进程,显示子进程、父进程pid、父进程ppid
//在父子进程输出printf()函数末尾必须加换行,或者flush(),刷新缓存,不然不能输出。
#include
#include
int main(int argc,const char *argv[])
{
pid_t pid;
pid=fork();
if(pid<0)
{
perror("Fail to fork");
return -1;
}
else if(pid==0)
{
printf("创建子进程成功,子进程pid:%d\n",getpid());
printf("父进程pid :%d\n",getppid());
}
else
{
printf("父进程pid:%d\n",getpid());
printf("父进程的父进程pid:%d\n",getppid());
}
while(1);//创建阻塞
return 0;
}
孤儿子进程:父进程结束了,子进程会编程孤儿子进程。
(1)return 结束一个函数的执行,程序不一定结束;
(2)void exit(int status)[库函数] ,需要添加 #include
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
(3)void _exit(int status)[系统调用],需添加 #include
#include
#include
#include
void func1()
{
printf("func1");
}
void func2()
{
printf("func2");
exit(0);//刷新缓冲区,可以在终端输出内容
//_exit(0);//当使用该函数时,系统调用,没有缓冲区,故不能在终端输出内容;
}
int main(int argc, const char* argv[])
{
func1();
func2();
return 0;
}
//示例:创建僵尸子进程
#include
#include
#include //exit()函数头文件
int main(int argc, const char *argv[])
{
pid_t pid;
pid=fork();//创建一个子进程
if(pid<0)
{
perror("Fail to fork");
return -1;
}
else if(pid==0)
{
sleep(3);
printf("child exit!\n");
exit(EXIT_SUCCESS);
}
else
{
}
while(1);
return 0;
}
// 子进程中断的原因
① exit()或_exit();//判断是exit()还是)_exit()使用宏函数 WIFEXITED(status),返回值为ture 则为exit(number),其中number =WEXITSTATUS(status);
#include
#include
#include
#include
#include
int main(int argc, const char *argv[])
{
pid_t pid ,pid2;
int status;
pid=fork();//创建一个子进程
if(pid<0)
{
perror("Fail to fork");
return -1;
}
else if(pid==0)
{
sleep(3);
printf("child exit!\n");
exit(100);
//return 0;
}
else
{
pid2=wait(&status); //父进程回收子进程,在子进程未结束时,父进程处于可中断等待态S
if(pid2<0)
{
perror("Fail to wait");
return -1;
}
if(WIFEXITED(status))//判断是exit() ,还是_exit(data)结束的子进程
{
printf("true is exit! exit(%d)\n",WEXITSTATUS(status));//子进程结束时的状态值为 data
}
printf("child exit pid =%d\n",pid2);//wait()返回值为子进程的pid号
}
while(1);
return 0;
}
② return // return 和exit()一样
③信号 //信号结束子进程,WIFSIGNALED(status)判断是否是由信号结束的(status是从wait(&status)获得的),是由信号结束的子进程,用WTERMSIG(status) 的返回值知道结束子进程的信号;
#include
#include
#include
#include
#include
int main(int argc, const char *argv[])
{
pid_t pid ,pid2;
int status;
pid=fork();//创建一个子进程
if(pid<0)
{
perror("Fail to fork");
return -1;
}
else if(pid==0)
{
sleep(100);
printf("child exit!\n");
exit(100);
}
else
{
pid2=wait(&status);
if(pid2<0)
{
perror("Fail to wait");
return -1;
}
if(WIFEXITED(status))
{
printf("true is exit! exit(%d)\n",WEXITSTATUS(status));
}
printf("child exit pid =%d\n",pid2);
if(WIFSIGNALED(status))//判断子进程是否是由信号中断,返回值为ture 则是
{
printf("子进程由信号中断,中断号:%d\n",WTERMSIG(status));//获得中断子进程的信号
}
}
while(1);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
int main(int argc, const char *argv[])
{
pid_t pid;
int fd;
ssize_t size1,size2;
char buf[1024]={0};
if(argc!=2)
{
fprintf(stderr,"Usage: %s log.txt",argv[0]);
return -1;
}
fd=open(argv[1],O_RDWR | O_CREAT | O_TRUNC,0666);
if(fd<0)
{
perror("Fail to fopen");
return -1;
}
pid =fork();
if(pid<0)
{
perror("Fail to fork()");
return -1;
}
else if(pid ==0)
{
int flag=0;
while(1)
{
usleep(300);
memset(buf,0,sizeof(buf));
ssize_t si=read(fd,buf,sizeof(buf));
if(si>0)
{
if(strncmp(buf,"quit",4)==0)
{
break;
}
printf("c:%s",buf);
}
}
}
else
{
char buf2[1024]={0};
while(1)
{
memset(buf,0,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
fflush(stdin);
lseek(fd,0,SEEK_SET);
size2=write(fd,buf,sizeof(buf));//把buf中的字符写入fd
lseek(fd,0,SEEK_SET);
if(strncmp(buf,"quit",4)==0)
{
wait(NULL);
close(fd);
break;
}
}
}
return 0;
}
//功能:回收子进程
//返回值:
//参数:
//pid -1 所有子进程,
#include
#include
#include
#include
#include
int main(int argc, const char *argv[])
{
pid_t pid ,pid2;
int status;
pid=fork();//创建一个子进程
if(pid<0)
{
perror("Fail to fork");
return -1;
}
else if(pid==0)
{
sleep(100);
printf("child exit!\n");
exit(100);
//return 0;
}
else
{
while(1)
{
pid2=waitpid(-1,&status,WNOHANG);//0 以阻塞的方式调用
if(pid2<0)
{
perror("Fail to wait");
return -1;
}
else if(pid2==0)
{
printf("pid2 =%d\n",pid2);
continue;
}
else
{
if(WIFEXITED(status))
{
printf("true is exit! exit(%d)\n",WEXITSTATUS(status));
}
printf("child exit pid =%d\n",pid2);
if(WIFSIGNALED(status))
{
printf("子进程由信号中断,中断号:%d\n",WTERMSIG(status));
}
}
}
}
//while(1);
return 0;
}
(1)前提:Linux 系统中,从终端运行的进程,当终端结束时,进程也结束。
(2)查看守护进程
ps -axj //其中TPGID为-1的为守护进程
(3)创建守护进程
//创建守护进程过程:
①创建子进程fork(),父进程退出"exit(EXIT_SUCCESS);
②在子进程中创建新的会话(脱离控制终端)setsid();
③改变进程的工作目录到|“/” :chdir(“/”);
④重设文件掩码 :umask(0);
⑤关掉不需要的文件描述符号:
close(0);//标准输入
close(1);//标准输出
close(2);//标准出错
//示例:守护进程每隔1秒在文件write_file 中打印:I am fine thank you!\n
紧急关闭 :killall -9 a.out
//多文件编程
head.h
#ifndef _HEAD_H_
#define _HEAD_H_
#include
#include
#include
#include
#include
#include
extern void demon_func();
#endif
//demo.c
#include
#include
#include
#include
#include
void demon_func()
{
pid_t pid;
pid=fork();
if(pid<0)
{
perror("Fail to fork");
return ;
}
else if(pid>0)
{
exit(EXIT_SUCCESS);
}
else
{
setsid();
chdir("/");
umask(0);
close(0);
close(1);
close(2);//关闭标准输入\输出\标准出错
}
}
//main.c
//创建守护进程
#include "head.h"
int main(int argc, const char *argv[])
{
int fd;
char buf[]={"I am fine, thank you!\n"};
fd=open("write_file",O_RDWR | O_CREAT | O_TRUNC,0666);
if(fd<0)
{
perror("Fail to open");
return -1;
}
demon_func();
while(1)
{
sleep(2);
write(fd,buf,strlen(buf));
}
close(fd);
return 0;
}
1.Linux 进程
2.Linux 线程
3.Linux进程间通信之无名管道通信
4.Linux进程间通信之有名管道通信
5.Linux 进程间通信—信号
6.进程间通信之IPC对象