C: read/write

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C: read/write相关的知识,希望对你有一定的参考价值。

参考技术A read() 函数从打开的设备或文件中读取数据,其函数原型如下:

参数count是请求读取的字节数,读上来的数据保存在缓冲区buf中,同时文件的当前读写位置向后移。当函数调用成功返回的是读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件末尾,则这次read返回0。
有些情况下,实际读到的字节数(返回值)会小于请求读的字节数count,例如:

write函数向打开的设备或文件中写数据:

与 read() 类似,写常规文件时, write的返回值通常等于请求写的字节数count,而向终端设备或网络写则不一定

对于不同的文件, read() 函数的阻塞情况不同:

同样,写常规文件是不会阻塞的,而向终端设备或网络写则不一定

对 Volatile.Read/Write 的理解

【中文标题】对 Volatile.Read/Write 的理解【英文标题】:understanding of Volatile.Read/Write 【发布时间】:2014-08-10 00:29:57 【问题描述】:

我正在尝试理解 C# Volatile 类。

如我所见:

Volatile.Write 方法强制写入 location 中的值 到通话点。此外,任何早期的程序顺序 加载和存储必须在调用 Volatile.Write 之前发生。

Volatile.Read 方法强制读取位置中的值 在通话点。此外,任何以后的程序顺序加载 并且存储必须在调用 Volatile.Read 之后发生。

这是否意味着在以下情况下:

internal sealed class ThreadsSharingData     
    private Int32 m_flag = 0;
    private Int32 m_value = 0;
    // This method is executed by one thread
    public void Thread1()         
        // Note: 5 must be written to m_value before 1 is written to m_flag
        m_value = 5;
        Volatile.Write(ref m_flag, 1);        
    

    // This method is executed by another thread
    public void Thread2()         
        // Note: m_value must be read after m_flag is read
        if (Volatile.Read(ref m_flag) == 1)
        Console.WriteLine(m_value);        
        

cpu 会等待Volatile.Write(ref m_flag, 1); 之前的命令,然后再开始写入m_flag

这对线程同步有何帮助?

【问题讨论】:

它仅与内存模型较弱的处理器相关,即获取和释放语义很重要的处理器。除了ARM内核之外,剩下的很少。它不是正确同步的替代品,编写没有同步的线程安全代码是一个非常先进的概念。否则,this question 已经很好地涵盖了。 【参考方案1】:

cpu 将等待 Volatile.Write(ref m_flag, 1); 之前的命令在开始写入 m_flag 之前?

哎呀,有点。更好的表达方式是:可以保证,如果任何其他线程看到 m_flag 设置为 1,他们也会看到 m_value 设置为 5。

这对线程同步有何帮助?

我不会说它有助于同步 - 但它确实有助于实现正确性。

如果您不使用 volatile 读取/写入,编译器/运行时/cpu 可能会重新排序 Thread1 方法中的两条指令,并且程序将能够打印 0、5 或什么都没有。

使用易失性读/写,程序将打印 5 或根本不打印,但从不 0。这是预期的行为。

【讨论】:

【参考方案2】:

这对线程同步有何帮助?

从设置命令执行顺序的意义上说,它无助于线程同步。它使您可以确保并发线程以特定顺序观察内存中值的更改,以防特定顺序对您的程序逻辑很重要。

[是否] CPU 在开始写入m_flag 之前等待Volatile.Write(ref m_flag, 1); 之前的命令?

不,写入m_value 的命令已经执行。但是,它的结果可能在 CPU 内核之外不可见 - 特别是,运行在不同内核上的线程可能会从 m_value 读取旧值 在向其写入 5 的命令之后执行完毕。这是因为新值可能在 CPU 的缓存中,而不是在内存中。

如果你写

m_value = 5;
m_flag = 1;

而不是Volatile.Write(ref m_flag, 1),另一个核心可能会以不同的顺序看到写入:首先它会看到m_flag变成1,然后它会看到m_value变成5。如果你的其他线程使用m_flag的值来判断m_value的有效性,那么逻辑可能会被破坏:例如Thread2可能偶尔会打印零。

【讨论】:

以上是关于C: read/write的主要内容,如果未能解决你的问题,请参考以下文章

linux下的read函数、write函数是属于直接I/O,为啥函数原型的第二项就是要将数据放到输入缓冲区内呢?

index [XXX] blocked by: [FORBIDDEN/12/index read-only / allow delete (api)]问题解决

关于readsCount、RPKM/FPKM、RPM(CPM)、TPM的理解

jxl读取excel导入到数据库,报错java.lang.NoClassDefFoundError: jxl/read/biff/BiffException

提取bam/sam文件指定区域reads

mac 终端安装 beautifulsoup4提示can't read /var/mail/bs4怎么解决