簡體   English   中英

檢查pthread互斥鎖是鎖定還是解鎖(線程鎖定后)

[英]Check to see if a pthread mutex is locked or unlocked (After a thread has locked itself)

我需要查看一個互斥鎖是否在if語句中被鎖定或解鎖,所以我這樣檢查它...

if(mutex[id] != 2){
    /* do stuff */
}

但是當我檢查它時,gcc給了我以下錯誤:

error: invalid operands to binary != (have 'ptherad_mutex_t' and 'int')

那么如何檢查互斥鎖是否被鎖定?

編輯:

我的問題的一個關鍵組成部分是我的線程(按設計)在將控制傳遞給另一個線程后立即鎖定自己。 因此,當線程A將控制傳遞給線程B時,線程A被鎖定,線程B執行某些操作,然后當線程B完成時,它將解鎖線程A.

這樣做的問題是,如果線程B嘗試解鎖線程A並且線程A尚未完成鎖定,則解鎖的調用將丟失,線程A保持鎖定狀態,從而導致死鎖。

更新:

我根據caf的建議重新制作了我的程序,但我仍遇到問題。 我已經將我的程序模擬到了盡可能最好的結構caf中,但我現在甚至無法分辨出導致死鎖的原因...我在這里創建了一個新問題尋求我的代碼幫助。

下面是caf的建議的可運行版本。 我在線程a的函數中做了一個小的重新排序,沒有它,線程a和線程b都會在創建時被鎖定,等待一個永遠不會改變的條件。

#include <pthread.h>

int run_a = 0;
pthread_mutex_t lock_a = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_a = PTHREAD_COND_INITIALIZER;

int run_b = 0;
pthread_mutex_t lock_b = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_b = PTHREAD_COND_INITIALIZER;

void *a(void *);
void *b(void *);

int main(){
    int status;
    pthread_t thread_a;
    pthread_t thread_b;

    pthread_create(&thread_a, NULL, a, (void *)0);
    pthread_create(&thread_b, NULL, b, (void *)0);

    pthread_join(thread_a, (void **)&status);
    pthread_join(thread_b, (void **)&status);

}

/* thread A */
void *a(void *i){
    while (1) {
        printf("thread A is running\n");
        sleep(1);

        /* unlock thread B */
        pthread_mutex_lock(&lock_b);
            run_b = 1;
            pthread_cond_signal(&cond_b);
        pthread_mutex_unlock(&lock_b);

        /* wait for thread A to be runnable */
        pthread_mutex_lock(&lock_a);
            while (!run_a)
                pthread_cond_wait(&cond_a, &lock_a);
            run_a = 0;
        pthread_mutex_unlock(&lock_a);      
    }
}

/* thread B */
void *b(void *i){
    while (1) {
        /* wait for thread B to be runnable */
        pthread_mutex_lock(&lock_b);
            while (!run_b)
                pthread_cond_wait(&cond_b, &lock_b);
            run_b = 0;
        pthread_mutex_unlock(&lock_b);

        printf("thread B is running\n");
        sleep(1);

        /* unlock thread A */
        pthread_mutex_lock(&lock_a);
            run_a = 1;
            pthread_cond_signal(&cond_a);
        pthread_mutex_unlock(&lock_a);
    }
}

您可以使用pthread_mutex_trylock 如果成功,互斥鎖無人認領,你現在擁有它(所以你應該釋放它並返回“unheld”,在你的情況下)。 否則,有人持有它。

我必須強調,“檢查互斥鎖是否無人認領”是一個非常糟糕的主意。 這種想法存在固有的競爭條件。 如果這樣的函數在時間t告訴你鎖是未被保持的,那么對於其他線程是否在t+1處獲得鎖定一無所知。

如果使用代碼示例更好地說明,請考慮:

bool held = is_lock_held();

if (!held)
{
  // What exactly can you conclude here?  Pretty much nothing.
  // It was unheld at some point in the past but it might be held
  // by the time you got to this point, or by the time you do your
  // next instruction...
}

互斥體不是您要實現的方案的正確原語。 你應該使用條件變量

int run_thread_a = 0;
pthread_mutex_t run_lock_a = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t run_cond_a = PTHREAD_COND_INITIALIZER;

int run_thread_b = 0;
pthread_mutex_t run_lock_b = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t run_cond_b = PTHREAD_COND_INITIALIZER;

/* thread A */
while (1) {
    /* Wait for Thread A to be runnable */
    pthread_mutex_lock(&run_lock_a);
    while (!run_thread_a)
        pthread_cond_wait(&run_cond_a, &run_lock_a);
    run_thread_a = 0;
    pthread_mutex_unlock(&run_lock_a);

    /* Do some work */

    /* Now wake thread B */
    pthread_mutex_lock(&run_lock_b);
    run_thread_b = 1;
    pthread_cond_signal(&run_cond_b);
    pthread_mutex_unlock(&run_lock_b);
}

/* thread B */
while (1) {
    /* Wait for Thread B to be runnable */
    pthread_mutex_lock(&run_lock_b);
    while (!run_thread_b)
        pthread_cond_wait(&run_cond_b, &run_lock_b);
    run_thread_b = 0;
    pthread_mutex_unlock(&run_lock_b);

    /* Do some work */

    /* Now wake thread A */
    pthread_mutex_lock(&run_lock_a);
    run_thread_a = 1;
    pthread_cond_signal(&run_cond_a);
    pthread_mutex_unlock(&run_lock_a);
}

每個線程將在pthread_cond_wait()阻塞,直到另一個線程發出信號喚醒它為止。 這不會死鎖。

通過為每個線程分配一個intpthread_cond_tpthread_mutex_t ,它可以很容易地擴展到許多線程。

您無法將pthread_mutex_t與int進行比較。

您可以使用

int pthread_mutex_trylock(pthread_mutex_t *mutex);

檢查一下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM