Thread can't count, giving wrong result

前端 未结 4 1050
闹比i
闹比i 2021-01-15 13:40

I wrote this piece of code

#include       /* Input/Output */
#include      /* General Utilities */
#include            


        
4条回答
  •  南笙
    南笙 (楼主)
    2021-01-15 13:53

    unsigned int cnt=0; is share-able among the threads and operation ++ is not atomically increase cnt. Two thread may read same values of cnt and increase, and overwrites cnt. You need to apply some concurrency control mechanism like semaphore, or mutex.


    If you would disassemble code using following command (suppose code name is thread1.c)

    ~$ gcc thread.c -lpthread -S  
    

    The output assembly code name is thread1.s.

    your wil find cnt++ is more then one instruction in low level in your code:

        movl    $0, -12(%ebp)
        jmp .L2
    .L3:
        movl    cnt, %eax
        addl    $1, %eax
        movl    %eax, cnt
        addl    $1, -12(%ebp)
    .L2:
        movl    NITERS, %eax
    

    (1) cnt fist move to %eax
    (2) then add one to %exc
    (3) move %eax into cnt back

    And due to thread context switching in between this line, same value of cnt is read by more than one threads. hence cnt++ is not atomic.

    Note: Global variable are thread shareable like cnt, and local variable like i that you declared in count() is thread specific.


    I modified your code and imposed concurrency control using semaphore, now it would work fine.

    Only modified code shown

    #include     /* POSIX Threads */
    #include 
    unsigned int cnt=0;  /*Count  variable%*/
    const int NITERS=1000;
    
    sem_t mysem;
    
    void count()
    {
        int i=0;
        for(i=0; i

    This will work good! some examples:

    nms@NMS:~$ ./thread 
    OK! cnt=2000
    nms@NMS:~$ ./thread 
    OK! cnt=2000
    nms@NMS:~$ ./thread 
    OK! cnt=2000
    

提交回复
热议问题