background image

  

   

 |---------------|------------|---------|------------|

      这样一来,一个命令就变成了一个整数形式的命令码。但是命令码非常的不直观,所
以 Linux Kernel 中提供了一些宏,这些宏可根据便于理解的字符串生成命令码,或者是
从命令码得到一些用户可以理解的字符串以标明这个命令对应的设备类型、设备序列号、

      这些宏我就不在这里解释了,具体的形式请读者察看 Linux 核心源代码中的文件里
给出了这些宏完整的定义。这里我只多说一个地方,那就是"幻数"。幻数是一个字母,数
据长度也是 8,所以就用一个特定的字母来标明设备类型,这和用一个数字是一样的,

 

只 是 更 加 利 于 记 忆 和 理 解 。 就 是 这 样 , 再 没 有 更 复 杂 的 了 。
    更多的说了也没有,读者还是看一看源代码吧,推荐各位阅读《Linux 设备驱动程序》
所带源代码中的 short 一例,因为它比较短小,功能比较简单,可以看明白 ioctl 的功能

 

  

   

 四

cmd

 

      这里确实要说一说,cmd 参数在用户程序端由一些宏根据设备类型、序列号、传送方
向、数据尺寸等生成,这个整数通过系统调用传递到内核中的驱动程序,再由驱动程序使
用解码宏从这个整数中得到设备的类型、序列号、传送方向、数据尺寸等信息,然后通过
  

   

 switch{case}

 

      要透彻理解,只能是通过阅读源代码,我这篇文章实际上只是一个引子。 Cmd 参数
的组织还是比较复杂的,我认为要搞熟它还是得花不少时间的,但是这是值得的,驱动

 

  

   

 

 

      ioctl 其实没有什么很难的东西需要理解,关键是理解 cmd 命令码是怎么在用户程序
里生成并在驱动程序里解析的,程序员最主要的工作量在 switch{case}结构中,因为
对设备的 I/O

 

控制都是通过这一部分的代码实现的。

flock()函数

当用户想使用函数 flock()来锁定一个文件时,可以使用两种不同的锁定类型:一个是共

享锁定,另一个是互斥锁定。如果用户采用共享锁定,若干个进程可以对某个文件拥有一个共

同的锁定;如果用户申请了一个互斥锁定,其他进程都无法对该文件进行锁定。因此,根据它
们的原理,用户可以对执行

读取操作

的系统采用一个共享锁定,而对执行

写入操作

的系统采

用一个互斥锁定。(摘自《Linux

 

编程宝典》)

    那么我就有疑问了: 

    1.既然读取操作的时候是不会对文件内容进行改变的,各个进程是不会相互冲突的,那么

 

为什么要锁定?锁定的意义何在?
    2.读取操作的时候使用共享锁定,也就是说,其它进程也可以锁定,那么是不是进行写操

 

作的进程也可以锁定也可以写入呢?共享锁定没有什么作用?

1.

若干进程在读,他们不会互相影响,但是,如果有进程写则会影响它们,所

 

以这个共享锁是防止有进程对文件写

2.

第二个问题和第一个问题关联,共享锁和独占锁互斥。

只有当一个程序试图施

加它自己的锁时,锁才会起作用;而没有尝试对文件上锁的程序仍然能够访
问该文件。因此,锁只能在协同工作的程序间起作用。

”(摘自《GNU/Linux 编

程指南》)

3.

据程序试验结果:当我对一个文件进行互斥锁定以后,然后进行共享锁定时,

——

锁定没有成功

这是因为互斥锁定是排斥其他锁定的;当我对一个文件进行

——

共享锁定以后,然后进行互斥锁定,锁定成功!

难道互斥锁定不排斥之前

的共享锁定?

请解答。

4.

我错在先关闭了文件描述符,当然共享锁定也就关闭了,随之互斥锁定必然也就能够成功 ,