当前位置: 首页 > news >正文

除了做视频网站还能做什么网站求网站都懂得

除了做视频网站还能做什么网站,求网站都懂得,网址导航网站制作工具,漂亮的网站建设中静态页TCP socket 接收函数 recv 发出 recvfrom 系统调用。 进⼊系统调⽤后#xff0c;⽤户进程就进⼊到了内核态#xff0c;通过执⾏⼀系列的内核协议层函数#xff0c;然后到 socket 对象的接收队列中查看是否有数据#xff0c;没有的话就把⾃⼰添加到 socket 对应的等待队列⾥…TCP socket 接收函数 recv 发出 recvfrom 系统调用。 进⼊系统调⽤后⽤户进程就进⼊到了内核态通过执⾏⼀系列的内核协议层函数然后到 socket 对象的接收队列中查看是否有数据没有的话就把⾃⼰添加到 socket 对应的等待队列⾥。最后让出CPU操作系统会选择下⼀个就绪状态的进程来执⾏。 假如我们没有使⽤ O_NONBLOCK 标记等待接收的过程会阻塞进程但是我们先探究阻塞的过程。 //file: net/socket.c SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t,size, unsigned int, flags, struct sockaddr __user *, addr,int __user *, addr_len) {struct socket *sock;//根据⽤户传⼊的 fd 找到 socket 对象sock sockfd_lookup_light(fd, err, fput_needed);......err sock_recvmsg(sock, msg, size, flags);...... }sock_recvmsg - __sock_recvmsg - __sock_recvmsg_nosec static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock,struct msghdr *msg, size_t size, int flags) {......return sock-ops-recvmsg(iocb, sock, msg, size, flags); }在之前的 socket 对象图中从图中看到 recvmsg 指向的是 inet_recvmsg 方法。 //file: net/ipv4/af_inet.c int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size, int flags) {...err sk-sk_prot-recvmsg(iocb, sk, msg, size, flags MSG_DONTWAIT,flags ~MSG_DONTWAIT, addr_len);这里又出现了一个 recvmsg 函数指针不过这个是socket 对象中的 recvmsg 方法对应 TCP 协议的 tcp_recvmsg 方法。 //file: net/ipv4/tcp.c int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,size_t len, int nonblock, int flags, int *addr_len) {int copied 0;...do {//遍历接收队列接收数据skb_queue_walk(sk-sk_receive_queue, skb) {...}...}if (copied target) {release_sock(sk);lock_sock(sk);} else //没有收到⾜够数据启⽤ sk_wait_data 阻塞当前进程sk_wait_data(sk, timeo); }可以看到消息量不够一样也会阻塞。 如果没有收到数据或者收到不⾜够多则调⽤ sk_wait_data 把当前进程阻塞掉。 //file: net/core/sock.c int sk_wait_data(struct sock *sk, long *timeo) {//当前进程(current)关联到所定义的等待队列项上DEFINE_WAIT(wait);// 调⽤ sk_sleep 获取 sock 对象下的 wait// 并准备挂起将进程状态设置为可打断 INTERRUPTIBLEprepare_to_wait(sk_sleep(sk), wait, TASK_INTERRUPTIBLE);set_bit(SOCK_ASYNC_WAITDATA, sk-sk_socket-flags);// 通过调⽤schedule_timeout让出CPU然后进⾏睡眠rc sk_wait_event(sk, timeo, !skb_queue_empty(sk-sk_receive_queue));...sk_wait_data 阻塞进程的实现 做完排队工作后给所在进程改个状态位即可。 ⾸先在 DEFINE_WAIT 宏下定义了⼀个等待队列项 wait。 在这个新的等待队列项上注册了回调函数 autoremove_wake_function并把当前进程描述符 current 关联到其 .private 成员上。 //file: include/linux/wait.h #define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function) #define DEFINE_WAIT_FUNC(name, function) \wait_queue_t name { \.private current, \.func function, \.task_list LIST_HEAD_INIT((name).task_list), \}紧接着在 sk_wait_data 中 调⽤ sk_sleep 获取 sock 对象下的等待队列列表头 wait_queue_head_t。 sk_sleep 源代码如下 //file: include/net/sock.h static inline wait_queue_head_t *sk_sleep(struct sock *sk) {BUILD_BUG_ON(offsetof(struct socket_wq, wait) ! 0);return rcu_dereference_raw(sk-sk_wq)-wait; }接着调⽤ prepare_to_wait 来把新定义的等待队列项 wait 插⼊到 sock 对象的等待队下。 //file: kernel/wait.c void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state) {unsigned long flags;wait-flags ~WQ_FLAG_EXCLUSIVE;spin_lock_irqsave(q-lock, flags);if (list_empty(wait-task_list))__add_wait_queue(q, wait);set_current_state(state);spin_unlock_irqrestore(q-lock, flags); }这样后⾯当内核收完数据产⽣就绪时间的时候就可以查找 socket 等待队列上的等待项进⽽就可以找到回调函数和在等待该 socket 就绪事件的进程了。 最后再调⽤ sk_wait_event 让出 CPU进程将进⼊睡眠状态这会导致⼀次进程上下⽂的开销。
http://www.zqtcl.cn/news/279548/

相关文章:

  • 大型门户网站开发北京网站建设管庄
  • 大连建设工程网站网站建设组织管理怎么写
  • wordpress英文站注册域名需要注意什么
  • 营销型网站的建设重点是什么深圳logo设计公司排名
  • 做网站的用什么软件呢网站排名优化服务公司
  • 网站开发完整视频网站集约化建设较好的城市
  • 网站建设和平面设计应用网站如何做
  • 自己做网站需要多少费用asa8.4 做网站映射
  • 商业网站 模板黑龙江省建设厅安全员考试
  • 网站新备案不能访问室内装修网站模板
  • 工程师报考网站wordpress设置视频图片不显示图片
  • 徐州网站建设公司排名成都住建平台
  • 用来备案企业网站国外免费外贸网站
  • 网页背景做的比较好的网站做一个企业网站价格
  • 免费制图网站县级门户网站建设的报告
  • 北京网站建设网怎么用手机做一个网站
  • 网站建设管理办法关于公司门户网站建设的议案
  • 网站开发入职转正申请书体验好的网站
  • 在线精品课程网站开发网站备案号怎么修改
  • 网站建设 风险百度热搜的含义
  • 怎样创作网站公司做网站 要准备哪些素材
  • 网站上的平面海报怎么做南阳企业做网站
  • 佛山公众平台网站推广多少钱wordpress如何调用分类目录
  • 网站推广应该注意什么信息发布平台推广
  • 官方网站案例做网站私活在哪接
  • 做网站滨州wordpress 不同域名
  • 找人做设计的网站广州做网站(信科网络)
  • 如何选择网站做站方向青之峰网站建设
  • 福州哪家网站制作设计高端还实惠设计logo的理念
  • 吉林市网站建设促销式软文案例