c - 得到错误的答案使用线程安全计数器

标签 c multithreading locking pthreads counter

我正在计算一个计数器直到 1000000,50 次使用 2 个线程。我正在使用 lock ,但每次都会得到不同的答案。为什么会这样。 我以为我会准确地得到计数器值 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

最佳答案

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

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);
    }
}

关于c - 得到错误的答案使用线程安全计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33647258/

相关文章:

sql-server - 是否有 SQL Server 相当于 PostgreSQL "select * for update"而不打开游标

c - 一个 glTexImage2D 问题

c++ - malloc_trim(0) 释放 Thread Arenas 的 Fastbins?

c++ - 如何使用 C 文件中的 esp8266 引脚排列?

c++ - 在同一个套接字上多次写入 C++

objective-c - Objective-C,NSThread分离与performSelectorInBackground

c# - 如何实现自己的锁定机制

sql - 未授权的访问独占锁 block 访问共享锁

C 错误 : "Called error is not a function or function pointer"

C 程序卡住,不进入 main()