回答错误使用线程安全计数器

时间:2015-11-11 09:07:09

标签: c multithreading locking pthreads counter

我计算一个计数器直到1000000,50次使用2个线程。我正在使用锁,但每次都会得到不同的答案。为什么会这样。 我以为我会得到正好1000000的计数器值,但它不是那样的。可能是什么原因?

#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<semaphore.h>
#define OPERATIONS 50
long unsigned int counter1=0;
pthread_mutex_t lock;

pthread_t tid[2];


void* myOperation()
{   
    while(counter1<1000000) {
        int pi=pthread_self();
        pthread_mutex_lock(&lock);  
        ++counter1;
        //printf("\n counter: %lu thread %d\n", counter1,pi);
        pthread_mutex_unlock(&lock);

    }
    return NULL;  
}

int main()
{
    int k = 0,p=0;;
    int err;

    int t=0;
    int i, j;
    i=0;


    for(j = 0; j < OPERATIONS; j++) {       
        counter1=0;
        k=0;

        while(k < 2) {
            err = pthread_create(&(tid[k]), NULL, &myOperation, NULL);
            if (err != 0)
                printf("\ncan't create thread :[%s]", strerror(err));
            k++;
        }
        pthread_join(tid[0], NULL);
        pthread_join(tid[1], NULL);

        printf("iiiiiiiiiiiii ----- %lu\n",counter1);
    }

    return 0;
}

输出:

iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000001
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000001
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000001
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000001
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000001
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000
iiiiiiiiiiiii ----- 1000000

1 个答案:

答案 0 :(得分:2)

你有三个问题。首先,您没有初始化您的互斥锁。你有一个静态互斥锁,所以你可以使用静态初始化器:

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

其次,你不应该在循环中调用pthread_mutex_destroy() - 只有当你再也不会使用互斥锁时才应该调用它。在这种情况下,使用静态互斥锁,您根本不需要调用pthread_mutex_destroy() - 它将在程序退出时清除。

第三个问题是你没有拿着锁就读counter1。这可能出错的一个例子是两个线程可以同时读取counter1并看到值999999 - 它们都决定增加它,所以它最终会达到1000001.你需要保持在决定递增计数器并实际递增计数器之间连续锁定。类似的东西:

void* myOperation()
{
    int finished = 0;

    while (!finished) {
        pthread_mutex_lock(&lock);
        if (counter1 < 1000000)
            ++counter1;
        else
            finished = 1;
        pthread_mutex_unlock(&lock);
    }
}