第六节:dup和dup2和原子操作——自己看视频随便记得,请不要参考。。

/*
第六节:dup和dup2和原子操作
原子是什么呢?原子时不可分割的最小单位,在这儿,原子操作是不可分割,如果有些操作可以分割就会造成竞争,所以原子操作不可分割

原子操作的作用:解决竞争和冲突。
前面课程提到,会使用原子操作,或者由于操作不原子而造成问题,例子:函数tmpnam,t它是创建临时文件,但是这个函数给你的是一个文件名,而不是一个直接可用的打开文件,前面分析过这个函数的缺陷,而给你一个另外的函数用,叫tmpfile,直接给你一个file * , 因为你并不关心文件名是多少,所以这个操作,tmpfile给了你一个可用的名字,然后下面我就去创建这个名字的文件,下面我一定会去fopen这些操作,别人可以从上面过程的中间插一脚,分配给你名字,还没来得及创建,你的时间片耗尽了,然后另外一个一个人也拿到同样的名字他先去创建了,等你再去创建就完蛋了。。为什么会出现这样的竞争,原因在于这两步操作并不原子,假如原子话的话,就成为不可分割的单位,拿到一个名字,马上创建,这两步是一起的,要么别人看到的状态是既没得到名字,也没创建文件。。要么就是既有名字,也有文件。。中间不会让别人插一脚。。tmpfile就是这样的。

temnem不让用,是因为他的操作不原子,我们在多进程多线程并发的时候,就要用到原子操作我来做的一系列步骤,别人看到的,要么我一个都没做,要么我全都做完了。。

原子操作就是用来解决竞争和冲突,,后面讲到多进程、多线程并发时解决竞争冲突首要的方式就是把某些操作原子化。

有一个概念:原子操作不可分割



dup dup2 
		例子如下
		首先下面的程序,是往终端上输出一个hello。。现在要做的操作你在上面做手脚,虚线行下面内容不变,我希望进程在执行是,hello没有在终端上,而是在一个我指定的文件中,可以define一个宏,来指定文件,,上面的操作如何实现呢?让puts函数不忘终端上输出。实际上puts的走向是往标准输出上去的,如果让你下面行不许变,你需要在上面做手脚,就意味着你需要在上面来对1做重定向
		
		不就是为了让你指定的文件占据1号吗,我可以在上面先关闭1号文件close(1),然后在后面打开open() 你指定的文件。。文件描述符的特点是优先使用当前可用范围内最小的那个值
			首先关闭1号文件close(1),然后在后面打开open() 你指定的文件。。打开方式读、
				我把1号标准输出关了,然后打开这个文件一定会占据一号,如果打开失败了就报错结束,说open失败
				下面我在输出不就是一号吗?按照道理上面操作就可以了。。
				
		然后把上述过程稍微变一下:用dup...我先产生一个文件描述符fd,然后下面dup的功能是复制一个文件描述符,dup会使用当前可用范围内(也就是没有用到的)最下的文件描述符作为新的描述符
			dupz作用:是把oldfd k拷贝一个副本,然后放到当前可用范围内最小的位置去。
			所以我当前先close(1),然后用dup,把oldfp 放到当前可用范围内最小的地方去。
			
			我原来占据就有这样一个文件描述符4号,然后现在占据请款是0到5都被用上了,然后,我再去执行dup,去把这个文件描述符复制一份,当前可用范围内最小的也就是6号了,所以说会把4号的副本放到6号,现在6号与4号是指向同一个结构体。其实我通过4和6来操作结构体,操作的是一个内容。。
			
		然后这样你在这儿close(1),,然后dup了一个副本的话,就好比4和6都指向同一个结构体,那么原来的那个文件描述符就可以被释放了,所以这块我们就来colse(fd),,相当远把原本关闭了,现在就剩下1号文件描述符,也就是你所关联的这个文件。。相当于输出重定向。
		
		
		这程序这样写不对。这个程序开始,就有了unix变成的感觉。。一个程序默认有0,1,2的,,如果现在当前进程默认没有1号,那么你第一次open时,你的fd默认就是1号,,然后你把1关了,下面的fd本省就不存在了,下面还去close(fd)..
			1、fd本身就是1
			2、考虑到,你旁边还有一个兄弟再跑,协同来操作这个文件,你的兄弟和你公用同样的文件描述符表,你一旦执行了close(1)刚关闭,还没来得及复制,你的兄弟在边上开了一个文件,那个文件顶到1号上去了,而你在去给你的fd=3,复制时,最多占用4,,其实你的puts输出可能输出到别的文件去了。之所有会照成上面的问题,原因在于上面两步操作不原子。。
			
			如果这块原子操作就可以了,close掉,马上复制上去,那块空间一定是复制的新的fd。。
			
				上面原子操作如何做?
					dup2需要你指定oldfd和newfd,功能是:把newfd作为oldfd的一个副本,,如果需要的话会把newfd关闭入宫newfd被占用的话,dup2会把newfd关闭然后把oldfd的副本,放到newfd的位置去
					
					所以dup2就是这两句话的原子操作
					
					dup2(fd,1);第一个参数,oldfd,第二个参数为newfd,是如何做?首先会close 1,然后把fd 放到1号去。。
					
			从结果上看没太大出入,这个程序这样写依然不对。。及fd如果本身是1如何办?
				dup2本身不会错,,如果oldfd本身是一个文件描述符,并且newfdh和oldfd相等的话,那么这个dup2什么也不做,换句话说:如果oldfd本身是1的话 newfd本身也是1。duo2什么也不做,dup2也不关1号,但是下面你自己关。close(fd);
					问题是你不能贸然去关闭fd,如果fd不等于1,你就可以我就关闭文件描述符,如果fd本身是1号,我就用1号。。
					
			上面的程序还是不对。。这个程序还有问题,会出现在后面。
			
			比如你程序执行到这个函数,你改变了标准输出的位置,这个模块结束之后,你要把这个打印之后原先的效果还原。,当自己在写小模块,不要当自己写main函数,。

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值