网络子系统84_sock事件通知进程

简介:
//	socket初始化
//	调用路径:inet_create->sock_init_data
1.1 void sock_init_data(struct socket *sock, struct sock *sk)
{
	...
	//sock状态改变的回调函数,当sock的状态变迁(如从established到close_wait)就会调用这个函数
	sk->sk_state_change	=	sock_def_wakeup;
	//sock有输入数据的时被调用
	sk->sk_data_ready	=	sock_def_readable;
	//sock有可写空间时被调用
	sk->sk_write_space	=	sock_def_write_space;
	//sock出错(如收到一个rst)会被调
	sk->sk_error_report	=	sock_def_error_report;
	sk->sk_destruct		=	sock_def_destruct;
	...
}


//	唤醒sock上阻塞的进程
//	步骤:
//		1.检查struct sock->sk_wq上是否有阻塞的进程
//			1.2 唤醒struct sock->sk_wq上的进程
2.1 static void sock_def_wakeup(struct sock *sk)
{
	struct socket_wq *wq;

	rcu_read_lock();
	wq = rcu_dereference(sk->sk_wq);
	if (wq_has_sleeper(wq))
		wake_up_interruptible_all(&wq->wait);
	rcu_read_unlock();
}


//	有可用输入数据
//	调用路径:raw_local_deliver->sock_def_readable
//	步骤:
//		1.检查struct sock->sk_wq上是否有阻塞的进程
//			1.1 唤醒struct sock->sk_wq上的进程
//		2.唤醒在用户空间设置了信号io的进程
2.2 static void sock_def_readable(struct sock *sk, int len)
{
	struct socket_wq *wq;

	rcu_read_lock();
	//sock的wait_queue
	wq = rcu_dereference(sk->sk_wq);
	//唤醒在wait_queue上等待可用数据的进程
	if (wq_has_sleeper(wq))
		wake_up_interruptible_sync_poll(&wq->wait, POLLIN | POLLPRI |
						POLLRDNORM | POLLRDBAND);
	//处理O_ASYNC
	sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
	rcu_read_unlock();
}

//	有可用输出空间
//	步骤:
//		1.判断是否有足够可用内存
//			1.1 空闲内存量 >= 50%
//		2.唤醒在wait_queue上等待可用内存的进程
//		3.处理信号io
2.3 static void sock_def_write_space(struct sock *sk)
{
	struct socket_wq *wq;

	rcu_read_lock();

	//判断是否有足够内存
	//	可用内存>=50%
	if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) {
		wq = rcu_dereference(sk->sk_wq);
		//唤醒wait_queue上的进程
		if (wq_has_sleeper(wq))
			wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
						POLLWRNORM | POLLWRBAND);
		//处理信号io
		if (sock_writeable(sk))
			sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
	}

	rcu_read_unlock();
}

//	sock发生错误
//		1. 检查sock上是否有进程在阻塞
//			1.1 唤醒进程有错误发生
//		2. 处理信号io
2.4 static void sock_def_error_report(struct sock *sk)
{
	struct socket_wq *wq;

	rcu_read_lock();
	wq = rcu_dereference(sk->sk_wq);
	if (wq_has_sleeper(wq))
		wake_up_interruptible_poll(&wq->wait, POLLERR);
	sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR);
	rcu_read_unlock();
}

目录
相关文章
|
2月前
|
运维 供应链 安全
构建网络环境的铜墙铁壁:从微软蓝屏事件反思系统安全与稳定性
【7月更文第22天】近期,一起由软件更新引发的“微软蓝屏”事件震撼全球,凸显了现代IT基础设施在面对意外挑战时的脆弱性。此事件不仅影响了数百万台设备,还波及航空、医疗、传媒等多个关键领域,造成了难以估量的经济损失和社会影响。面对这样的挑战,如何构建更为稳固和安全的网络环境,成为了全球IT行业共同面临的紧迫任务。
73 3
|
8天前
|
网络协议 C语言
C语言 网络编程(十三)并发的TCP服务端-以进程完成功能
这段代码实现了一个基于TCP协议的多进程并发服务端和客户端程序。服务端通过创建子进程来处理多个客户端连接,解决了粘包问题,并支持不定长数据传输。客户端则循环发送数据并接收服务端回传的信息,同样处理了粘包问题。程序通过自定义的数据长度前缀确保了数据的完整性和准确性。
|
8天前
|
C语言
C语言 网络编程(八)并发的UDP服务端 以进程完成功能
这段代码展示了如何使用多进程处理 UDP 客户端和服务端通信。客户端通过发送登录请求与服务端建立连接,并与服务端新建的子进程进行数据交换。服务端则负责接收请求,验证登录信息,并创建子进程处理客户端的具体请求。子进程会创建一个新的套接字与客户端通信,实现数据收发功能。此方案有效利用了多进程的优势,提高了系统的并发处理能力。
|
12天前
|
算法 安全 网络安全
探索操作系统核心:进程调度的奥秘网络安全的盾牌与剑——漏洞防御与加密技术
【8月更文挑战第30天】在数字世界的每一次点击和命令背后,都隐藏着一个不为人知的英雄——进程调度器。它默默无闻地在后台工作,确保我们的命令得以流畅执行。本文将揭开这位幕后英雄的面纱,带你了解进程调度的原理、重要性以及它是如何在操作系统中发挥作用的。无论你是编程新手还是资深开发者,理解进程调度都能帮你更好地掌握计算机的运作原理。准备好深入操作系统的核心,一探究竟了吗?让我们开始吧!
|
15天前
|
数据采集 Java Python
python 递归锁、信号量、事件、线程队列、进程池和线程池、回调函数、定时器
python 递归锁、信号量、事件、线程队列、进程池和线程池、回调函数、定时器
|
16天前
|
安全 网络安全 调度
云计算与网络安全:云服务、网络安全、信息安全等技术领域深入理解操作系统:进程调度的奥秘
【8月更文挑战第27天】本文将探讨云计算与网络安全之间的关联,包括云服务、网络安全、信息安全等技术领域。我们将通过代码示例来展示如何保护云计算环境中的数据和应用程序。最后,我们将讨论如何应对云计算环境中的网络安全挑战,以保护数据和应用程序免受攻击。
|
2月前
|
缓存 安全 Web App开发
Chrome插件实现问题之网络进程接收到URL请求后会如何解决
Chrome插件实现问题之网络进程接收到URL请求后会如何解决
|
2月前
|
机器学习/深度学习 数据采集 监控
Python基于BP神经网络算法实现家用热水器用户行为分析与事件识别
Python基于BP神经网络算法实现家用热水器用户行为分析与事件识别
|
4月前
|
数据采集 存储 C++
单线程 vs 多进程:Python网络爬虫效率对比
本文探讨了Python网络爬虫中的单线程与多进程应用。单线程爬虫实现简单,但处理速度慢,无法充分利用多核CPU。而多进程爬虫通过并行处理提高效率,更适合现代多核架构。代码示例展示了如何使用代理IP实现单线程和多进程爬虫,显示了多进程在效率上的优势。实际使用时还需考虑代理稳定性和反爬策略。
单线程 vs 多进程:Python网络爬虫效率对比
|
4月前
|
调度 iOS开发
网络事件触发自动登录
网络事件触发自动登录
37 2