Potential for Race Conditions in Reader/Writer Pseudocode

微笑、不失礼 提交于 2019-12-12 05:25:33

问题


I'm analysing the following pseudocode for race conditions (a bit of self practise) and looking at where the possibilities are. The pseudocode describes a vague asynchronous reader/writer.

Writer Thread

r = 0; w = 1; l = 2; //assign start slot numbers
while(1) { 
  write_slot(w);
  l = w; //last written slot is w 
  w = not(r,l) //assigns next slot so that w is neither r or l
}

Reader Thread

while(1) {
 r = l; //read from latest write
 read(r);
}

The possibilities of corruption/race conditions I've found so far are if the variables read/writes are not atomic and so, for example, the writer could change the value of l whilst the reader is halfway through reading it (could lead to a nonsensical value of r through torn read/write). Is there any race conditions however that could potentially lead to both the reader and writer attempting to access the same slot?


回答1:


The fundamental problem is that even variable assignment is not an atomic operation. The difficulty is in how your pseudocode would be executed in hardware. Most computers use a "load/store" architecture where values from memory must be moved to a register before being moved to another memory location (i.e. there are no direct memory-to-memory operations). This introduces an intermediate state (the register) that could possibly mix things up in a multi-threaded situation such as this.

I'm assuming that you would implement r, w, and l as variables in memory that would be visible to both threads. Globals and heap memory are shared between threads of the same process, so this part is easy. However, threads must have their own stack and register states, otherwise they just wouldn't work.

An assignment such as the reader's line r = l; would first load a value from some memory location (wherever l is stored) into a register, then store this value to memory (wherever r is stored). So the assignment r = l would be something like the "pseudo-assembly":

    load   r1,addr(l)     ; load l from memory into register r1
    store  addr(r),r1     ; store register r1 to wherever r is kept

where r1 is some register, addr(l) is the memory address of wherever l is stored, and addr(r) is the address of r.

The problem in your case is that the register of one thread (say, the reader) could keep an intermediate value while another thread (writer) modifies memory. The first thread (the reader) would then overwrite this memory when storing from register to memory.

Consider the following sequence of events. The notation [writer] and [reader] specify which thread is doing what. The reader's assignment r = l is given as the above assembly operations, for which the writer performs troublesome operations in between:

    [writer]  r=0; w=1; l=2;    // (given starting conditions)
    [writer]  write_slot(w)     // w==1
    [reader]  load r1,addr(l)   // load l (value 2) into register r1
    [writer]  l = w;            // l gets w, which is 1
    [writer]  w = not(r,l)      // since r *in memory* is still 0,
                                //   and l in memory is 1,
                                //   this picks 2 for w.
    [reader]  store addr(r),r1  // stores 2 to r *in memory*
    [reader]  read(r)           // read(2) since r==2
    [writer]  write_slot(w)     // write(2) since w==2

The last two operations could then occur in parallel and so they would be attempting to access the same slot at the same time. So the answer to your question is yes, it could happen.

One way to fix something like this is to enforce mutual exclusion: ensuring that some segment of code is uninterrupted by making other threads wait. There are special hardware instructions (like "compare & exchange" CMPXCHG) and operating system features (like suspending thread execution) used to implement mutual exclusion. Typically you would use some library to do synchronization for you and not try to write your own technique. For example, see pthread_mutex_lock() and pthread_mutex_unlock() of the POSIX thread library for C.



来源:https://stackoverflow.com/questions/34928199/potential-for-race-conditions-in-reader-writer-pseudocode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!