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

专业装修设计网站网站模版asp

专业装修设计网站,网站模版asp,网站排名下降的原因,治疗腰椎间盘突出的特效药参考博客链接: https://blog.51cto.com/liulixiaoyao/533469 socketpair创建了一对无名的套接字描述符(只能在AF_UNIX域中使用),描述符存储于一个二元数组eg. s[2] 这对套接字可以进行双工通信,每一个描述符既可以读也…

参考博客链接:
https://blog.51cto.com/liulixiaoyao/533469

socketpair创建了一对无名的套接字描述符(只能在AF_UNIX域中使用),描述符存储于一个二元数组eg. s[2] 这对套接字可以进行双工通信,每一个描述符既可以读也可以写。
这个在同一个进程中也可以进行通信,向s[0]中写入,就可以从s[1]中读取(只能从s[1]中读取),也可以在s[1]中写入,然后从s[0]中读取;但是,若没有在0端写入,而从1端读取,则1端的读取操作会阻塞,即使在1端写入,也不能从1读取,仍然阻塞;反之亦然…

验证所用代码:

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <error.h> 
#include <errno.h> 
#include <sys/socket.h> 
#include <stdlib.h> #define BUF_SIZE 30 int main(){ int s[2]; int w,r; char * string = "This is a test string"; char * buf = (char*)calloc(1 , BUF_SIZE); if( socketpair(AF_UNIX,SOCK_STREAM,0,s) == -1 ){ printf("create unnamed socket pair failed:%s\n",strerror(errno) ); exit(-1); } /*******test in a single process ********/ if( ( w = write(s[0] , string , strlen(string) ) ) == -1 ){ printf("Write socket error:%s\n",strerror(errno)); exit(-1); } /*****read*******/ if( (r = read(s[1], buf , BUF_SIZE )) == -1){ printf("Read from socket error:%s\n",strerror(errno) ); exit(-1); } printf("Read string in same process : %s \n",buf); if( (r = read(s[0], buf , BUF_SIZE )) == -1){ printf("Read from socket s0 error:%s\n",strerror(errno) ); exit(-1); } printf("Read from s0 :%s\n",buf); printf("Test successed\n"); exit(0); 
} 

若fork子进程,然后在服进程关闭一个描述符eg. s[1] ,在子进程中再关闭另一个 eg. s[0] ,则可以实现父子进程之间的双工通信,两端都可读可写;当然,仍然遵守和在同一个进程之间工作的原则,一端写,在另一端读取;

这和pipe有一定的区别,pipe是单工通信,一端要么是读端要么是写端,而socketpair实现了双工套接字,也就没有所谓的读端和写端的区分

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <error.h> 
#include <errno.h> 
#include <sys/socket.h> 
#include <stdlib.h> #define BUF_SIZE 30 int main(){ int s[2]; int w,r; char * string = "This is a test string"; char * buf = (char*)calloc(1 , BUF_SIZE); pid_t pid; if( socketpair(AF_UNIX,SOCK_STREAM,0,s) == -1 ){ printf("create unnamed socket pair failed:%s\n",strerror(errno) ); exit(-1); } /***********Test : fork but don't close any fd in neither parent nor child process***********/ if( ( pid = fork() ) > 0 ){ printf("Parent process's pid is %d\n",getpid()); close(s[1]); if( ( w = write(s[0] , string , strlen(string) ) ) == -1 ){ printf("Write socket error:%s\n",strerror(errno)); exit(-1); } }else if(pid == 0){ printf("Fork child process successed\n"); printf("Child process's pid is :%d\n",getpid()); close(s[0]); }else{ printf("Fork failed:%s\n",strerror(errno)); exit(-1); } /*****read***In parent and child****/ if( (r = read(s[1], buf , BUF_SIZE )) == -1){ printf("Pid %d read from socket error:%s\n",getpid() , strerror(errno) ); exit(-1); } printf("Pid %d read string in same process : %s \n",getpid(),buf); printf("Test successed , %d\n",getpid()); exit(0); 
} 

以上代码中在父子进程之间各关闭了一个描述符,则在父进程写可从子进程读取,反之若子进程写,父进程同样可以读取;大家可以验证下

另外,我也测试了在父子进程中都不close(s[1]),也就是保持两个读端,则父进程能够读到string串,但子进程读取空串,或者子进程先读了数据,父进程阻塞于read操作!

之所以子进程能读取父进程的string,是因为fork时,子进程继承了父进程的文件描述符的,同时也就得到了一个和父进程指向相同文件表项的指针;若父子进程均不关闭读端,因为指向相同的文件表项,这两个进程就有了竞争关系,争相读取这个字符串.父进程read后将数据转到其应用缓冲区,而子进程就得不到了,只有一份数据拷贝(若将父进程阻塞一段时间,则收到数据的就是子进程了,已经得到验证,让父进程sleep(3),子进程获得string,而父进程获取不到而是阻塞)

有网友"笨笨"回复:

“若将父进程阻塞一段时间,则收到数据的就是子进程了,已经得到验证,让父进程sleep(3),子进程获得string,而父进程获取不到”

我验证的情况是,父进程一直阻塞在read上。我想不明白,为什么这时候父进程不能读取数据呢。
而上一种情况,父进程先读取数据,子进程仍然可以读取数据(数据为空),但子进程不会阻塞在read上。

关于这个问题,解释如下:

1.该网友说的情况的确存在,如果先让子进程sleep,此时父进程获得数据,子进程被唤醒之后读到EOF返回;若是让父进程sleep先,子进程先获取数据,之后父进程被唤醒却是一直阻塞不能返回.按理来说这两种情况应该没差别,这个区别下文描述.

2.对于网友提到问题的这个测试,我最初的目的是想说明如果通过产生子进程的方式,对一个写端同时有多个读端,这这些读端之间相互竞争.我们可以用个更有说服力的测试方法来看出这个问题.原来的测试是让一个进程sleep然后另一个进程读完所有字符,可以看到之后醒来的进程就读不到任何字符了.更好的方法是先有一个进程读取一部分的字符,然后第二个进程被唤醒,会发现这第二个进程还能读到一些字符,而这些字符是第一个进程读完剩下的.

3.第一条中的遗留问题,为什么这两种情况有不同的表现.

原因是:如果子进程先sleep,父进程读取完数据之后,父进程退出,此时写端s[0]的引用计数变为0(之前子进程已主动close了一次),被系统释放,根据read的语义,当子进程被唤醒后会读取到EOF;但是当我们先让父进程sleep的时候,子进程读取完后退出,由于写端在父进程,没有被释放,所以父进程此时阻塞在读操作上.

用另外一个测试来证明,我们在子进程中不主动执行close[0],也就是有两个写端,然后其他不变,子进程先sleep,父进程先读取到数据然后退出,但此时更刚刚有个区别,父进程退出的时候s[0]这个写端的描述符并不会减到0,因为子进程中还持有一个引用,所以写端健在,子进程被唤醒之后不会读到EOF返回,而是阻塞在读操作上

最后,有关socketpair在内核中实现的一点点描述:

socketpair会创建两个描述符,但改描述符不属于任何的实际文件系统,而是网络文件系统,虚拟的.同时内核会将这两个描述符彼此设为自己的peer即对端(这里即解决了如何标识读写端,可以想象,两个描述符互为读写缓冲区,即解决了这个问题).然后应用相应socket家族里的read/write函数执行读写操作.

有了这个基础,即可明白为什么试用fork产生的两个子进程都不关闭读端的时候会竞争,如上所述,他们共享相同的文件表项,有相同的inode和偏移量,两个进程的操作当然是相互影响的.


下边这段是我自己的理解:首先因为fork,所以有两对管道,即两个s[0]和两个s[1],s[0]和s[1]都可以做读端或者写端
正常的程序是:父进程关闭s[1],子进程关闭s[0],这样一来,就只剩一对管道,s[0] (父进程) 和s[1](子进程)
父进程往s[0]写入数据,子进程从s[1]中读取数据,没问题。
接下来看博主的测试:
父子进程都不关闭s[1],也就是只有子进程关了一个s[0],剩下两个s[1],一个s[0]
他们所属进程是:父进程拥有s[0],s[1],子进程拥有s[1]
依旧是父进程往s[0]中写入数据,此时有两个读端,即父子进程都有的s[1]。
分两种情况:
子进程先读,而且把数据都读完,那么父进程再读的时候就会阻塞(此时写端s[0]还未关闭)。
而反过来父进程先读,把数据读完之后,父进程退出,关闭自己的s[0],s[1]
此时子进程再读会读到EOF,因为写端已经关闭了。

最后以一个问题结尾:
linux pipe();父进程需要close(fd[0]);子进程close(fd[1]);为什么都需要关闭一个?
在这里插入图片描述
另外找到不错的关于socketpair的博文:
https://blog.csdn.net/weixin_40039738/article/details/81095013

http://www.yayakq.cn/news/377656/

相关文章:

  • 化妆品网站建设的设计思路wordpress做淘宝客网站
  • 镇江网站推广优化个人网页设计与实现ppt
  • 百度教育网站网络营销的八大能力
  • 允许发外链的网站怎样用西瓜影音做网站
  • 郑州网站建设价格源码制作网站
  • 营销型网站制作平台环境设计网站推荐
  • 网站建设的一些专业术语网站文字规划
  • 校园网站建设的作用网站开发有前途么
  • 网站可以个人做吗网站的建站标准
  • 男女做那个暖暖网站龙岗网站建设设计服务
  • 大连 找人做网站利川住房和城乡建设局网站
  • 中国建设部网官方网站下载app赚钱的平台
  • 网络公司网站设计阿里云模板建站怎么样
  • 做seo网站的公司哪家好wordpress斜杠自动成-
  • 建设营销型网站不足之处自己怎么做游戏软件
  • php 网站目录结构网站建设管理工作计划
  • 提供o2o网站建设网页模板下载在线
  • 黑龙江省营商环境建设监督局网站西安有什么好玩的东西
  • 重庆高端品牌网站建设长沙房地产管理局
  • 如何做彩票网站代理太原专门做网站
  • 全国加盟网站官网wordpress房产企业模板免费下载
  • 苏州网站开发公司有哪些网站购物车怎么做
  • h5技术的网站如何更改网站域名
  • 网站建设哪个公司比较好上海网站怎么备案表
  • 百度网站html验证umu互动平台
  • 黑龙江省住房和城乡建设厅网站百度代运营公司
  • 网站建设申请计划房屋平面设计图软件
  • 福建城市建设厅网站wordpress数据存储
  • 域名网站查询成都到西安火车时刻表查询
  • 网站可以做10000件事情吗有额度的购物app商城