I'm sorry that my expression may confuse you. I try to make it more clear. My requirement is that clients to incr/decr a value must be atomic, that get from slabber and add 1 must be an atomic operation according to clients(php clients or libmemcached etc.). If two clients incr a value 1, the value should be 3, not that B client overwrite the value, and the final value is still 2. This operation in Non-thread is atmoic, because they are not in concurrent environment, and only one event is processed one time.
But now I found in multithread version it is not atomic, if put the item_get in add_delta, this may be done, but too many locks. I wonder if you understand my meaning, anyway, Cheers, Steve On Tue, Feb 26, 2008 at 12:34 AM, dormando <[EMAIL PROTECTED]> wrote: > > Steve Chu wrote: > > On Mon, Feb 25, 2008 at 4:28 PM, dormando <[EMAIL PROTECTED]> wrote: > >> Steve Chu wrote: > >> > On Mon, Feb 25, 2008 at 2:51 PM, dormando <[EMAIL PROTECTED]> wrote: > >> >> I think this is fine? > >> >> > >> >> Since the operations are independently atomic, it's perfectly valid > for > >> >> two threads to incr the same value. > >> >> > >> > > >> > But for client api, they seems NOT atomic, because when Thread A just > >> > has 'item_get' done but before 'add_delta', Thread B can still do > >> > item_get. > >> > > >> > X-> set "foo" 1 > >> > A-> item_get "foo" > >> > B-> item_get "foo" > >> > A-> add_delta "foo" by 1 > >> > B-> add_delta "foo" by 1 > >> > > >> > then A and B both hold value 2, which one should be stored? > >> > > >> > And the exact value we need is 3, right? I am not quit sure, correct > >> > me if i am wrong:) > >> > >> The result gets copied into the thread-local 'temp' buffer, then copied > >> into that connection (implicitly atomic)'s output buffer. > >> > >> So actually I read the code wrong the first time. This _should_ do the > >> right thing: > >> > >> We have threads (A, B, X): > >> > >> X -> set 'foo' 1 > >> > >> A -> process_arithmetic_command() > >> note thread local storage (char temp[]) > >> B -> same. > >> > >> A -> it = item_get(key, nkey) > >> (atomically increments the refcount for that item, returns a reference > >> to it) > >> B -> same, same time. > >> (same) > >> > >> A -> out_string(c, add_delta(it, incr, delta, temp)); > >> add_delta runs atomically, copies the result of the addition into the > >> thread local 'temp' buffer and _returns the 'temp' buffer_ (which > >> contains 2) > >> B -> out_string(c, add_delta(it, incr, delta, temp)); > >> Gets serialized behind A, and its 'temp' then holds a value one higher > >> than A's (containing 3) > > > > Here I am confused. Every thread has a local var 'temp' and here > > 'temp' should hold 2. 'temp' is independent, and doesn't share > > between threads. So thread B should overwrite the value in the > > slabber. Am I right? > > Yes, it does. Just like it would if the increments happened at > completely different times. Since the result of the addition is copied > into the connection's write buffer atomically, this doesn't upset the > balance of the universe. > > Or are you talking about something else? > > -Dormando > > -- Steve Chu http://stvchu.org
