帝国CMS做的淘客网站,怀化举报网站,中国互联网电视app下载安装,asp网站安装到空间每个进程的用户空间都是独立的#xff0c;不能相互访问。 所有进程的内核空间(32位系统3G-4G)都是共享的 应用场景
作为缓冲区#xff0c;处理速度不同的进程之间的数据传输资源共享#xff1a;多个进程之间共享同样的资源#xff0c;一个进程对共享数据的修改#xff0c… 每个进程的用户空间都是独立的不能相互访问。 所有进程的内核空间(32位系统3G-4G)都是共享的 应用场景
作为缓冲区处理速度不同的进程之间的数据传输资源共享多个进程之间共享同样的资源一个进程对共享数据的修改别的进程应该立刻看到数据传输 一个进程需要将它的数据发送给另一个进程发送的数据量在一个字节到几兆字节之间通知事件一个进程需要向另一个或一组进程发送消息通知它它们发生了某种事件如进程终止时要通知父进程进程控制有些进程希望完全控制另一个进程的执行如Debug进程此时控制进程希望能够拦截另一个进程的所有陷入和异常并能够及时知道它的状态改变。
一、管道 缺点缓存区在内核中大小受限只能承载无格式字节流单向通信方式低效不适合频繁交换数据 生命周期随着进程创建而建立随着进程终止而消失
遵循先进先出原则不支持 lseek 之类的文件定位操作
需要双方通信时需要建立起两个管道
读端不读或者读的慢写端要等待读端
读端关闭写端收到SIGPIPE信号直接终止
写端不写或者写的慢读端要等待写端
写端关闭读端读完pipe内部的数据然后再读会读到0为止表明读到文件结尾匿名管道 pipe
特殊文件只存在于内存没有存在于文件系统中
只能用于有亲缘关系的进程间
shell 命令中的竖线就是匿名管道
pipe() 和 fork() 搭配有名管道 fifo mkfifo myfifo #在文件系统中创建一个类型为 p 的设备文件 int mkfifo(const char *pathname, mode_t mode); //默认在当前的路径下创建
mkfifo(myfifo, 0666);
open(myfifo, O_RDONLY);
open(MY_FIFO, O_WRONLY);二、System V 进程间通信操作系统层面上进程间通信方案 消息队列和共享内存是以传输数据为目的 信号量是为了保证进程间的同步与互斥而设计的 消息队列 是消息的链表,存放在内核中并由消息队列标识符标识 缺点通信不及时有大小限制在内核中一条消息最大长度MSGMAX 和一个队列的最大长度MSGMNB(以字节为单位), 不适合比较大数据的传输用户态与内核态之间的数据拷贝开销 共享内存 – 最快的IPC 映射一段能被其它进程访问的内存,这段共享内存由一个进程创建,多个进程均能访问 带来新的问题多进程间竞争共享资源常与信号量配合使用 生命周期是随内核的,进程要主动删除其创建的共享内存ipcrm -m {shmid} 共享内存块的大小都必须是系统页面大小的整数倍。系统页面大小指的是系统中单个内存页面包含的字节数。在 Linux 系统中内存页面大小是4KB不过您仍然应该通过调用 getpagesize 获取这个值通过man 2 getpagesize查看
#include sys/ipc.h
#include sys/shm.h // shmget
#include sys/types.h // key_t
// key_t ftok(const char *pathname, int proj_id); //获取key值
// int shmget(key_t key, size_t size, int shmflg); //得到共享内存标识符,不存在时创建并返回
// void* shmat(int shmid, const void *shmaddr, int shmflg); //共享内存绑定到当前进程的地址空间中
// int shmdt(const void *shmaddr); //取消共享内存与进程地址空间之间的关联
// int shmctl(int shmid, int cmd, struct shmid_ds *buf); //cmd表示具体控制动作:IPC_STAT,IPC_SET改变状态,IPC_RMID 删除key_t key ftok(PATH_NAME, PROJ_ID);//获取key值
shmid shmget(key, SIZE, IPC_CREAT | IPC_EXCL); //操作系统给用户返回的id// ipcs命令查看有关进程间通信设施的信息
// -q列出消息队列相关信息。
// -m列出共享内存相关信息。
// -s列出信号量相关信息信号量 一个整型的计数器表示资源的数量。两原子操作 P 操作: 把信号量 -1。相减后信号量 0表明还有资源可使用进程可正常继续执行否则进程需阻塞等待 V 操作: 把信号量 1。相减后信号量 0表明当前没有阻塞中的进程否则表明当前有阻塞中的进程将该进程唤醒运行
信号用于通知接收进程某个事件已经发生唯一的异步通信机制。缺点传递信息少 信号事件来源主要: 硬件来源如键盘 CltrC 和 软件来源如 kill 命令 可以在任何时候发送信号给某一进程一旦有信号产生进程就对信号处理(执行默认操作,定义一个信号处理函数,忽略信号) # CtrlC 产生 SIGINT 信号表示终止该进程
# SIGTERM 终止该进程通过 Core Dump 将当前进程的运行状态保存在文件里面方便事后分析问题在哪里
# CtrlZ 产生 SIGTSTP 信号表示停止该进程但还未结束
kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN1 36) SIGRTMIN2 37) SIGRTMIN3
38) SIGRTMIN4 39) SIGRTMIN5 40) SIGRTMIN6 41) SIGRTMIN7 42) SIGRTMIN8
43) SIGRTMIN9 44) SIGRTMIN10 45) SIGRTMIN11 46) SIGRTMIN12 47) SIGRTMIN13
48) SIGRTMIN14 49) SIGRTMIN15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX套接字3个属性域、类型、协议。唯一的跨网络主机的通信机制
// domain: AF_INET 用于 IPV4、
// AF_INET6 用于 IPV6
// AF_LOCAL/AF_UNIX 二者等价用于本机
// type: SOCK_STREAM 字节流对应 TCP
// SOCK_DGRAM 数据报对应 UDP
// SOCK_RAW 原始套接字
int socket(int domain, int type, int protocal);TCP 服务端负责监听的 socket 叫作监听 socket listen_fd 调用 accept 时连接成功会返回一个已完成连接的 socket叫作已完成连接 socket sock_fd用来后续传输数据。 是「两个」 不同 socket UDP 是没有连接的所以不需要三次握手。不存在客户端和服务端的概念 每次通信时调用 sendto 和 recvfrom都要传入目标主机的 IP 地址和端口 本地 socket 的实现效率大大高于 IPv4 和 IPv6 的字节流、数据报 socket 实现 不像 TCP 和 UDP 要绑定 IP 地址和端口而是绑定一个本地文件
三、POSIX 进程间通信共享内存、消息队列、信号量、
参考https://www.cnblogs.com/tongh/p/18002994 Linux内核v2.6.6和glibc2.3.4之后的版本支持POSIX消息队列 ldd --version POSIX可移植操作系统接口是IEEE为要在各种UNIX操作系统上运行的软件而定义的一系列API标准的总称其正式称呼为IEEE 1003而国际标准名称为ISO/IEC 9945 标准线上地址注册后可以在线阅读或者下载。 IEEE和Open Group 的POSIX认证 相关页面 20世纪80年代中期Unix厂商试图通过加入新的、往往不兼容的特性来使它们的程序与众不同。局面非常混乱麻烦也就随之而来了。为了提高兼容性和应用程序的可移植性阻止这种趋势 IEEE(电气和电子工程师协会)开始努力标准化Unix的开发后来由 Richard Stallman命名为“Posix”。 这套标准涵盖了很多方面比如Unix系统调用的C语言接口、shell程序和工具、线程及网络编程 有了这个规范就可以调用通用的API 消息队列 优点 灵活支持多种数据类型和优先级。 可靠消息持久化且不会因发送者崩溃而丢失。 高效支持大量数据的传输和并行处理 缺点 数据复制的开销。 需要管理访问权限以确保安全性。
#include fcntl.h
#include sys/stat.h
#include mqueue.hmqd_t mq_open(const char *name, int oflag, ...); //打开一个已存在的消息队列或创建一个新的消息队列
//发送消息
int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio);
int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout);//接收消息
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio);
ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio, const struct timespec *abs_timeout);//设置/获取消息队列的属性
int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat);
int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat, struct mq_attr *omqstat);int mq_close(mqd_t mqdes); //关闭
int mq_unlink(const char *name); //删除一个命名的消息队列。共享内存
#include sys/mman.h
#include sys/stat.h /* For mode constants */
#include fcntl.h /* For O_* constants */int shm_open(const char *name, int oflag, mode_t mode); //创建或打开一个POSIX共享内存对象
int ftruncate(int fd, off_t length); //设置大小
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); //映射到进程的地址空间
int munmap(void *addr, size_t length); //解除映射
int shm_unlink(const char *name); //删除共享内存对象信号量 有名信号量:操作系统内核维护的具有全局唯一名字的信号量 无名信号量是一种不具有全局唯一名字的信号量通常只能在相关的进程或线程之间进行共享 只有0和1两种取值的信号量叫做二进制信号量 #include fcntl.h
#include sys/stat.h
#include semaphore.hsem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value); //创建或打开有名信号量
int sem_init(sem_t *sem, int pshared, unsigned int value); //初始化无名信号量int sem_getvalue(sem_t *sem, int *sval); //获取当前信号量的值
int sem_post(sem_t *sem); //V操作信号量 1
int sem_wait(sem_t *sem); //等待信号量减小。如果信号量的值大于0则将其减小1并立即返回否则会阻塞当前线程直到信号量变为大于0为止
int sem_trywait(sem_t *sem); //尝试等待信号量减小的非阻塞版本。如果信号量的值大于0则将其减小1并立即返回否则会立即返回并且不会阻塞当前线程
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); //函数允许设置一个超时时间如果在指定的时间内未能获得信号量函数将返回一个特定的错误码int sem_close(sem_t *sem); //关闭有名信号量
int sem_destroy(sem_t *sem); //销毁无名信号量
int sem_unlink(const char *name); //从系统中删除有名信号量
操作系统发展历史