如何使用pthread_mutex_trylock?

Aqu*_*irl 9 c mutex pthreads

使用trylock:

FILE           *fp;
pthread_mutex_t demoMutex;

void * printHello (void* threadId)
{
    pthread_mutex_trylock (&demoMutex);

    pthread_t      writeToFile = pthread_self ();
    unsigned short iterate;
    for (iterate = 0; iterate < 10000; iterate++)
    {
        fprintf (fp, " %d ",  iterate,         4);
        fprintf (fp, " %lu ", writeToFile, sizeof (pthread_t));
        fprintf (fp, "\n",     writeToFile, 1);
    }

    pthread_mutex_unlock (&demoMutex);
    pthread_exit (NULL);
}
Run Code Online (Sandbox Code Playgroud)

然后是main():

int main ()
{
    pthread_t        arrayOfThreadId [5];
    int                  returnValue;
    unsigned int iterate;

    fp = fopen ("xyz", "w");
    pthread_mutex_init (&demoMutex, NULL);

    for (iterate = 0; iterate < 5; iterate++)
    {
        if (returnValue = pthread_create (&arrayOfThreadId [iterate],
                                    NULL,
                                    printHello,
                                    (void*) &arrayOfThreadId [iterate]) != 0)
        {
            printf ("\nerror: pthread_create failed with error number %d", returnValue);
        }
    }

    for (iterate = 0; iterate < 5; iterate++)
        pthread_join (arrayOfThreadId [iterate], NULL);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这里输出首先打印一些第一个线程然后打印其余部分,然后再打印第一个线程.锁不起作用.如果我更换相同的pthread_mutex_lock东西,每个东西都会顺序显示!

这里有什么荒谬的错误?

caf*_*caf 28

pthread_mutex_trylock()没有测试结果就打电话没有意义.

如果未能获得互斥体,你应该进入临界区,你应该晚解锁.例如,您可以像这样重写它(请注意,您对如何fprintf()调用也非常困惑):

void *printHello(void *threadId)
{
    if (pthread_mutex_trylock(&demoMutex) == 0)
    {
        unsigned short iterate;
        for (iterate = 0; iterate < 10000; iterate++)
        {
            fprintf (fp, " %d\n", iterate);
        }

        pthread_mutex_unlock (&demoMutex);
    }

    pthread_exit (NULL);
}
Run Code Online (Sandbox Code Playgroud)

但是,使用它pthread_mutex_lock()代替可能更有意义pthread_mutex_trylock(),因此如果争用的话,你的线程将等待互斥锁可用. pthread_mutex_lock()在几乎所有情况下都是你想要的; 该_trylock变体仅用于优化一些不寻常的情况 - 如果您遇到_trylock需要的情况,您就会知道.


小智 6

...
while (pthread_mutex_trylock(&demoMutex) == 0)
...
Run Code Online (Sandbox Code Playgroud)

你的代码毫无意义.强行锁定在哪里?这就像一个不工作的螺旋锁使用更多的CPU?!

trylock锁定时返回0,所以:

if(!pthread_mutex_trylock(&demoMutex))
{
  // mutex locked
}
Run Code Online (Sandbox Code Playgroud)

如果获取了互斥锁引用的互斥对象上的锁,则pthread_mutex_trylock()函数将返回零.否则,返回错误号以指示错误.


小智 6

caf 对如何使用它有很好的回答。我只需要为自己解释这个解释,但是我确实了解到pthread_mutex_lock()课堂上的开销要大得多,并且只是使用<time.h>lib对其进行了测试,并且我的循环的性能显着提高。只是加上那两美分,因为他提到也许你应该pthread_mutex_lock()改用!

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NUM_THREADS 4
#define LOOPS 100000

int counter;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// using pthread_mutex_lock
void* worker() {
    for (int i = 0; i < LOOPS; i++) {
        pthread_mutex_lock(&mutex);
        counter++;
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit(NULL);
}

// using try_lock - obviously only use one at a time
void* worker() {
    for (int i = 0; i < LOOPS; i++) {
        while (pthread_mutex_trylock(&mutex) != 0) {
            // wait - treated as spin lock in this example
        } 

        counter++;
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit(NULL);
}

int main(int argc, char *argv[]) {
    clock_t begin = clock();
    pthread_t t[NUM_THREADS];
    int rc;

    counter = 0;

    for (int i = 0; i < NUM_THREADS; i++) {
        rc = pthread_create(&t[i], NULL, worker, NULL);

        if (rc) {
            printf("Thread #%d failed\n", i);
        }
    }

    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(t[i], NULL);
    }

    printf("%d\n", counter);
    clock_t end = clock();
    double time = (double)(end - begin) / CLOCKS_PER_SEC;

    printf("Time Spent: %f", time);

    return 0;   
}
Run Code Online (Sandbox Code Playgroud)

很明显,你会注释掉一个工人来测试它,但如果你尝试一下,我得到Time Spent: 1.36200的平均值为pthread_mutex_lock()Time Spent: 0.36714pthread_mutex_trylock()

如果你使用 Atomics,速度会更快。