并发服务器

本文介绍了服务器并发处理的三种模型:多进程、多路复用和多线程,详细讲解了进程创建、销毁、通信以及线程的创建、同步与销毁。还探讨了边缘触发和水平触发的异同,强调了线程在进程内的执行流和内存共享,以及线程同步中的互斥量和信号量机制。
摘要由CSDN通过智能技术生成

多进程服务器:通过创建多个进程提供服务(一个程序运行的过程中也会产生多个进程)

多路复用服务器:通过捆绑并同意管理I/O对象提供服务

多线程服务器:通过生成与客户端等量的线程提供服务

进程:占用内存空间的正在运行的程序

无论进程是怎么创建的,所有进程都会从操作系统分配到ID。此ID称为“进程ID(PID)”,其值为大于2的整数。1要分配给操作系统启动后的(用于协助操作系统)首个进程,因此用户进程无法得到ID值1 。

创建进程:

#include<unistd.h>

pid_t fork(void);//成功返回进程ID,失败返回-1

fork函数将创建调用的进程副本。也就是说,并非根据完全不同的程序创建进程,而是复制正在运行的、调用fork函数的进程。另外,两个进程都将执行fork函数调用后的语句(准确说是在fork函数返回后)。但因为通过同一个进程、复制相同的内存空间,之后的程序流要根据fork函数的返回值加以区分。

父进程(原进程,即调用fork函数的主体):fork函数返回子进程ID

子进程(通过父进程调用fork函数复制出的进程):fork函数返回0

调用fork函数后,父子进程拥有完全独立的内存结构。

进程销毁和进程创建同等重要,如果没有销毁进程,它们将变成僵尸进程,占用系统中的重要资源。

终止fork函数产生的子进程:

1. 传递参数并调用exit函数

2. main函数中执行return语句并返回值。

将子进程变成僵尸进程的正是操作系统:exit函数传递的参数值和main函数的return语句返回的值都会传递给操作系统,而操作系统不会销毁子进程,直到把这些值传递给产生该子进程的父进程。处在这种状态下的进程就是僵尸进程。

僵尸进程应该何时销毁:向创建子进程的父进程传递子进程的exit参数值或return语句的返回值。操作系统不会主动把这些值传递给父进程,只有父进程主动发起请求(函数调用)时,操作系统才会传递该值。换句话说:如果父进程未主动要求获得子进程的结束状态值,操作系统将一直保存,并让子进程长时间处于僵尸进程状态。

僵尸进程的进程状态为Z+

销毁僵尸进程1:利用wait函数

#include<sys/wait.h>

pid_t wait(int* statloc);//成功返回终止的子进程ID,失败返回-1

调用此函数时如果已有子进程终止,那么子进程终止时传递的返回值(exit函数的参数值、main函数的return返回值)将保存到该函数的参数所指内存空间。注意:该函数参数指向的单元中还包括其他信息,需要通过下列宏进行分离:

1. WIFEXITED: 子进程正常终止时返回“真”

2. WEXITSTATUS: 返回子进程的返回值

调用wait函数时,如果没有已终止的子进程,那么程序将阻塞直到有子进程终止,因此需谨慎调用该函数。

销毁僵尸进程2:利用waitpid函数

#include<sys/wait.h>

pid_t waitpid(pid_t pid, int* statloc, int options);//成功返回终止的子进程ID(或0),失败返回-1

//pid:等待终止的目标子进程的ID,若传递-1,则与wait函数相同,可以等待任意子进程终止

//statloc:与wait函数的statloc参数具有相同含义

//options:传递头文件sys/wait.h中声明的常量WNOHANG , 即使没有终止的子进程也不会进入阻塞状态,而是返回0并退出函数

即,调用waitpid函数时,程序不会阻塞

#include<signal.h>

void(*signal(int signo , void (*func)(int)))(int);//为了在产生信号时调用,返回之前注册的函数指针

函数名:signal

参数:int signo , void(* func)(int)

返回类型:参数类型为int,返回void型函数指针

调用上述函数时,第一个参数为特殊情况信息,第二个参数为特殊情况下将要调用的函数的地址值(指针)。发生第一个参数代表的情况时,调用第二个参数所指的函数。

SIGALRM:已到通过调用alarm函数(闹钟函数)注册的时间

SIGINT:输入CTRL+C

SIGCHLD:子进程终止

#include<unistd.h>

unsigned int alarm(unsigned int seconds);//返回0或以秒为单位的距SIGALRM信号发生所剩时间

如果调用该函数的同时向它传递一个正整型参数,相应时间后(以秒为单位)将产生SIGALRM信号。若向该函数传递0,则之前对SIGALRM信号的预约将取消。如果通过该函数预约信号后未指定该信号对应的处理函数,则(通过调用signal函数)终止进程,不做任何处理。

发生信号时,将唤醒由于调用sleep函数而进入阻塞状态的进程。调用函数的主体的确是操作系统,但进程处于睡眠状态时无法调用函数。因此,产生信号时,为了调用信号处理器,将唤醒由于调用sleep函数而进入阻塞状态的进程。而且,进程一旦被唤醒,就不会再进入睡眠状态。即使还未到sleep函数中规定的时间也是如此。

sigaction函数可以完全代替signal函数&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值