进程知识点
来源:互联网 发布:南京烘焙培训班 知乎 编辑:程序博客网 时间:2024/05/31 13:14
进程:运行起来的程序(动态性,并发性,独立性,异步行)
三态:就绪---(调度)---执行---(条件不足)---阻塞---(读数据)读完又成就绪态
程序:静态的
进程互斥:硬件资源或者软件资源不能同时被两个进程同时使用就会产生互斥
临界资源:在进程互斥当中同一时刻只允许一个进程访问的资源
进程的同步:一组并发进程按一定的顺序执行的过程A--B--C
进程调度:按一定算法,从一组待执行的进程中选出一个来占有CPU(抢占式调度和非抢占式调度)
调度算法:先来先服务调度算法,短进程优先调度算法,高级优先级调度算法(不同系统中不同优先级特性),时间片算法(公平调度法)
死锁:多个资源因竞争资源形成一种僵局
获得ID
#include<sys/types.h>
#include<unistd.h>
pid_t getpid(void)//本次进程的ID
pid_t getppid(void)//获取父进程的ID
进程创建-fork();
pid_t fork(void)
fork()被调用一次,返回两次,可能有三个返回值
1,在父进程中,返回新创建的子进程的PID;
2,在子进程中,返回0;
3,如果出现错误,返回一个负值;
#include<sys/types.h>
#include<unistd.h>
int main(void)
{
pid_t pid;
int count=0;//数据空间,堆栈空间全部拷贝,代码段共享
pid=fork();
count++;
printf("count=%d\n",count);
return 0;
}
pid_t vfork();
fork:子进程拷贝父进程的数据段,父子进程的执行次序不确定
vfork:子进程与父进程共享数据段,子进程先运行,父进程后运行
exec函数族
exec不会创建新的进程,用被执行的程序替换它调用的函数
int execl(const char *path,const char*arg1,...)//可执行文件完整路径
execl.c
#include<unistd.h>
main()
{
execl("/bin/ls","ls","-al","/etc/passwd",(char *)0);
}
int execlp(const char*path,const char *arg1,...)//可执行文件名
int execv(const char*path,char *const arg[])//把要执行的命令放在argv[]数组里了
int system(const char* string)
#include<stdlib.h>
void main()
{
system("ls -a /etc/passwd");
}
进程等待
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int *status)
进程间通信原因:
1,数据传输
2,资源共享
3,通知事件
4,进程控制
linux进程发展:UNIX进程间通信--基于System V进程间通信----POSIX(Portable Operating System Interface)进程间通信
linux进程间通信方式
1,pipe无名管道(父子进程之间的通信)和FIFO有名管道(实质是文件)
管道:单项的,先入先出,写(尾部),读(头部)
创建无名管道:int pipe(int filedis[2]);filedis[0]读,filedis[1]写
关闭无名管道:close(pipe_fd[0]),close(pipe_fd[1]);
必须在系统调用fork()前调用pipe(),否则子进程将不会继承文件描述符
//父子进程之间的通信
#include<unistd.h>
#include<errno.h>
#include<sys.types.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{
int pipe_fd[2];
pid_t pid;
char buf_r[100];
char *p_wbuf;
int r_num;
memset(buf_r,0,sizeof(buf_r));
if(pipe(pipe_fd)<0)
{
printf("pipe creat error!\n");
return -1;
}
if(pipe(pipe_fd)==0)
{
printf("\n");
close(pipe_fd[1]);
sleep(2);
if(r_num=read(pipe_fd[0],buf_r,100)>0)
{
printf("%d numbers read from the pipe is %s\n",r_num,buf_r);
}
close(pipe_fd[0]);
exit(0);
}
else if(pid_t>0)
{
close(pipe_fd[0]);
if(write(pipe_fd[1],"hello",5)!=-1)
printf("parent write1 hello!\n");
if(write(pipe_fd[1],"pipe",5)!=-1)
printf("parent write2 pipe!\n");
close(pipe_fd[1]);
sleep(3);
waitpid(pid,NULL,0);
exit(0);
}
}
有名管道
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char * pathname,mode_t mode)
mode-->O_NONBLOCK:没使用管道没数据进程会阻塞,使用了管道没数据,立刻出错返回
#include<unistd.h>
#include<errno.h>
#include<sys.types.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define FIFO "/tmp/myfifo"
main(int argc,char ** argv)
{
char buf_r[100];
int fd;
int nread;
if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!EEXIST))
printf("cannot creaat fifoserver\n");
printf(preparing for reading bytes...\n);
memset(buf_r,0,sizeof(buf_r));
fd=open(FIFO,O_CREAT|O_NONBLOCK,0);
if(fd==-1)
{
perror("open");
exit(1);
}
while(1)
{
memset(buf_r,0,sizeof(buf_r));
if((nread=read(fd,buf_r,100))==-1)
{
if(errno=EAGAIN)
printf("no data yet\n");
}
printf("read %s from FIFO\n",buf_r);
sleep(1);
}
pause();
}
2,信号signal
产生信号的方式:
按键、硬件异常(除数为0、无效的存储访问)、进程kill函数给另一个进程发送信号、kill命令给进程返送信号
进行信号处理:忽略次信号(SIGKILL、SIGSTOP除外)、执行用户希望的动作、执行系统默认动作(大多数默认处理是终止该进程)
发送信号:kill(自己给自己发,也可以给别人发)、raise(只能给自己发)
int kill(pid_t pid,int signo)
int raise(int signo)
alarm(给自己发信号)SIGALRM
unsigned int alarm(unsigned seconds)//多少秒后给自己发信号
pause函数:使进程等待直到收到信号为止
int pause(void)
只有执行了一个信号处理函数后,挂起才结束
#include<signal.h>
void(*signal(int signo,void(*func)(int)))(int)
func:SIG_IGN(忽略此信号)、SIG_DFL(默认方式)、信号处理函数名(使用该函数处理)
typedef void(*sighandler_t)(int)
sighandler_t signal(int signum,sighandler_t handler)
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
void my_func(int sign_no)
{
if(sign_no==SIGINT)
printf("I have get SIGINT\n");
else if(sign_no==SIGQUIT)
printf("I have get SIGQUIT\n");
}
int main()
{
printf("Waiting for signal SIGINT or SIGQUIT\n");
signal(SIGINT,my_func);
signal(SIGQUIT,my_func);
pause();
exit(0);
}
kill -s SIGQUIT 3687//发送信号
3,共享内存:被多个进程共享的一部分物理内存
步骤:创建共享内存:shmget
int shmget(key_t key,int size,int shmflg)
映射:shmat
int shmat(int shmid,char *shmaddr,int flag)
解除映射:int shmdt(char *shmaddr)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#define PERM S_IRUSR|S_IWUSR
int main(int argc,char **argv)
{
int shmid;
char *p_addr,*c_addr;
if(argc!=2)
{
fprintf(stderr,"Usage:%s\n\a",argv[0]);
exit(1);
}
if(shmid=shmget(IPC_PRIVATE,1024,PERM)==-1)
{
fprintf(stderr,"Creat Share Meemory Error:%s\n\a",strerror(errno));
exit(1);
}
if(fork())
{
p_addr=shmat(shmid,0,0);
memset(p_addr,'\0',1024);
strncpy(p_addr,argv[1],1024);
wait(NULL);
exit(0);
}
else
{
sleep(1);
c_addr=shmat(shmid,0,0);
printf("Client get %s\n",c_sddr);
exit(0);
}
}
4,消息队列(消息的链表)
信号能够传送的西诺西辆有限,管道则只能传送无格式的字节流
POSIX消息队列以及系统V消息队列
随着内核持续,消失:内核重新启动、人工删除
键值:
#include<sys/types.h>
#include<sys/ipc.h>
key_t ftok(char *pathname,char proj)//返回文件名对应的键值
打开创建:
#include<sys/msg.h>
int msgget(key_t key,int msgflg)//key:IPC_PRIVATE
msgflg:IPC_CREAT:创建新的消息队列
IPC_EXCL:要创建的消息队列已经存在,则返回错误
IPC_NOWAIT:读写消息队列要求无法满足时,不阻塞
发送消息:
int msgsnd(int msqid,struct msgbuf * msggp,int msgsz,int msgflg)
//消息格式
struct msgbuf
{
long mtype://消息类型>0
char mtex[1];//消息数据的首地址
}
int msgrcv(int msqid,struct msgbuf *msgp,int msgsz,long msgtype,int msgflg)
#include<stdio.h>
#include<sys/types.h>
#include<sys/msg.h.h>
#include<unistd.h>
struct msg_buf{
int mtype;
char data[255];
}
int main(void)
{
key_t key;
int msgid;
struct msg_buf msgbuf;
key=ftok("/tmp/2",'a');//把想使用的文件名转化为键值
printf("key=[%x]\n",key);
msgid=msgget(key,IPC_CREAT|0666);
if(msgid==-1){
printf("create error\n");
return -1;
}
msgbuf.mtype = getpid();
strcpy(msgbuf.data,"test haha");
ret=msgsnd(msgid,&magbuf,sizeof(msgbuf.data),IPC_NOWAIT);
if(ret==-1){
printf("send message error!\n");
return -1;
}
memset(&msgbuf,0,sizeof(msgbuf));
ret=msgrcv(msgid,&msgbuf,sizeof(msgbuf.data),getpid(),IPC_NOWAIT);
if(ret==-1){
printf("recive message error!\n");
return -1;
}
printf("rcv msg=[%s]\n",msgbuf.data);
}
5,信号量(保护临界资源)
#include<sys/sem.h>
int semget(key_t key,int nsems/*创建信号量的个数*/,int semflg)
int semop(int semid,struct sembuf *sops,unsigned nsops/*指向数组元素的个数*/)
struct senbuf{
unsigned short sem_num;
short sem_op;
short sem_flg:
}
//6,套接字(socket)
- 进程知识点
- 进程知识点
- 僵尸进程孤儿进程知识点
- 进程、线程 知识点整理
- 进程和线程知识点
- 进程、线程知识点随笔
- 进程的基础知识点
- 线程和进程知识点
- 有关进程的小知识点
- Android知识点之进程优先级
- Android知识点之进程优先级
- Java线程进程相关知识点
- OS中关于进程线程的知识点
- 进程间通信的简单知识点
- linux进程通讯和线程同步知识点
- 进程环境 知识点汇总《APUE》 chapter-7
- 进程和线程--重磅推出--知识点梳理
- 进程与线程的基本知识点
- C++中extern “C”含义深层探索
- execCommand全集
- PopupWindow
- 操作系统内存管理机制
- Nullable<T> 的实现
- 进程知识点
- Program received signal SIGPIPE, Broken pipe.
- linux vi 工具使用
- 黑马程序员-javaIO学习笔记
- VC 中socket编程步骤
- 代理(Proxy)模式的浅解
- 创建split按钮
- 多态性
- 啊哈,临床执业医师考试一次通过了,自己庆祝下吧!