linux进程
2019-10-01
Linux 中线程就是共享上下文的进程
- 用
fork()
创建进程
#include<stdio.h>//printf()
#include<unistd.h> //fork()
...
pid_t pid;
pid = fork()//创建进程
if(pid == 0)
{
printf("child PID [%d], getpid = %d, getppid = %d\n",pid,getpid(),getppid());
}
else
{
printf("parent PID [%d], getpid = %d, getppid = %d\n",pid,getpid(),getppid());
}
printf("%d finish",pid);
运行结果:
child PID [0], getpid = 12420, getppid = 12419
0 end
parent PID [12420], getpid = 12419, getppid = 21696
12420 end
相当于利用父进程创建了一个子进程并从fork()开始向下进行
- 孤儿进程 父进程结束子进程并不会强制结束 利用sleep使父进程先运行结束 运行结果:
parent PID [13469], getpid = 13468, getppid = 21696
13469 end
child PID [0], getpid = 13469, getppid = 2031
0 end
可以看到子进程的父进程改变了(孤儿进程
托孤给init进程, 每个进程都必须有父进程)
- 僵尸进程
和
孤儿进程
相反 当子进程先结束的时候 子进程必须等到父进程捕获到了子进程的结束状态才能真正退出 可以看到僵尸进程
ps -a
PID TTY TIME CMD
15887 pts/19 00:00:00 fuck1
15888 pts/19 00:00:00 fuck1 <defunct>
僵尸进程
被<defunct>
标记(如果系统中存在过多的僵尸进程, 将会使得新的进程不能产生)
- 用
vfork()
创建进程 需要使用exit()
来结束进程vfork()
创建出来的进程会和父进程共享数据(共享内存) 并且会阻塞父进程(保证子进程先执行) 如果子进程的执行依赖父进程的进一步操作则会产生死锁
- pipe通信
//pipe只能单向通信
//必须在
fork()
之前调用pipe(pipeTemp)
管道入口: write(pipeTemp[1],msg,strlen(msg)+1)
管道出口: read(pipeTemp[0],msg,strlen(msg)+1)
在父/子进程中将不需要的口关闭close(pipeTemp[n])
- 消息队列
//send.c
int msgid = msgget((key_t)1234, 0666 | IPC_CREAT);//创建消息队列
msgsnd(msgid, (void*)&data, MAX_TEXT, 0)//向消息队列发送消息
//receive.c
int msgid = msgget((key_t)1234, 0666 | IPC_CREAT);//创建消息队列
msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0)//从消息队列获取消息///msgtype指定请求的消息类型
msgctl(msgid, IPC_RMID, 0)//删除消息队列
- 共享内存
system("ipcs -m")
获取共享内存信息
shm_id = shmget(IPCKEY, 1028, 0640 | IPC_CREAT | IPC_EXCL);//创建共享内存
p_setting = (st_setting *)shmat(shm_id, NULL, 0);//将共享内存映射到进程虚拟地址空间
/*使用共享内存p_setting*/
shmdt(p_setting)//从进程地址空间移除共享内存
shmctl( shm_id, IPC_RMID, NULL)//删除共享内存