2013-12-16 81 views
0

當我在pthread編程互斥我用來使互斥鎖變量(pthread_mutex_t mutex)全球。當我看到很多示例程序大部分情況下互斥變量放在全局。如何通過本地使用互斥鎖變量來鎖定線程?

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
void *add1_fun(void* arg); 
void *add2_fun(void* arg); 
pthread_mutex_t mutex; 

void *add1_fun(void* arg) 
{ 
    int t_num = (int)arg; 
    int i = 0; 

    pthread_mutex_lock(&mutex); 

    printf("Thread %d created and running \n", t_num); /*critical section start*/ 
    sleep(3); 
    printf("Thread %d finishes the work\n", t_num); /*critical section end*/ 
    pthread_mutex_unlock (&mutex); 

    pthread_exit(NULL); 
} 

int main(int argc, char *argv[]) 
{ 
    pthread_t mythread1; 
    pthread_t mythread2; 
    pthread_attr_t myattr; 
    void *joinResult; 
    int x = 0; 
    int t_arg = 1; 
    pthread_mutex_init(&mutex, NULL); 
    pthread_attr_init(&myattr); 
    pthread_attr_setdetachstate(&myattr, PTHREAD_CREATE_JOINABLE);     

    if((pthread_create(&mythread1, &myattr, add1_fun, (void*)t_arg) != 0)){ 
     printf("Error, thread not created properly\n"); 
     return 1; 
    } 
    t_arg = 2; 
    if((pthread_create(&mythread2, &myattr, add1_fun, (void*)t_arg) != 0)){ 
     printf("Error, thread not created properly\n"); 
     return 1; 
    } 
    pthread_attr_destroy(&myattr); 
    if(pthread_join(mythread1, &joinResult) != 0){ 
     printf("Error pthread join \n"); 
     return 1; 
    } 
    printf("Main : Thread1 joined with result of %d\n", (int)joinResult); 
    if(pthread_join(mythread2, &joinResult) != 0){ 
     printf("Error pthread join \n"); 
     return 1; 
    } 
    printf("Main : Thread2 joined with result of %d\n", (int)joinResult); 
    printf("main finishes the work\n"); 

    pthread_exit(NULL); 
} 

什麼是我的疑問是,在這種情況下無處不在的程序可以採取互斥鎖變量和 就鎖定和解鎖互斥。這會降低安全性。

是否可以通過在線程處理程序中本地創建互斥鎖變量來鎖定線程。像下面的程序結構

void *add1_fun(void* arg) 
{ 
    pthread_mutex_t mutex; 
    pthread_mutex_lock(&mutex); 

/* critical section */ 

    pthread_mutex_unlock (&mutex); 
} 
int main() 
{ 
    /* code */ 
} 

我覺得這個問題可能沒有意義,請幫幫我,我不擅長多線程。

我在linux下使用gcc。

謝謝。

+1

您正在使用「安全」一詞。你有什麼樣的對手和威脅? –

回答

6

局部變量僅侷限於特定的函數調用。如果你想讓一個「本地」變量在函數調用之間是靜態的,那麼你必須創建變量static

+0

謝謝!你的答案對我有幫助。 – sujin

5

互斥體的想法是每個人都可以嘗試鎖定它,但是在任何時候只有一個人會成功。

如果使用本地互斥鎖,則可以鎖定它。但其他線程將創建自己的本地互斥鎖,並且也會成功鎖定它。不是真正的重點,它是...

如果你不想使用全局互斥量,你可以聲明它爲atatic,然後,每個人都會使用相同的互斥量。

4

的問題是,如果你宣佈一個互斥體作爲一個局部變量的函數,如:

void foo() { 
    pthread_mutex_t mutex; 
    /* ... */ 
} 

這是行不通的,因爲每次有人調用foo(),它「創造」一個全新的互斥體,它不能用於同步調用到foo(),因爲兩個調用方不會鎖定相同的互斥體。

唯一的解決辦法,如果你不想放置「互斥」變量在一些全球性的文件或類似的,就是要聲明是靜態

void foo() { 
    static pthread_mutex_t mutex; 
    /* ... */ 
} 

但是,請記住,這是反正全球互斥!這意味着,你可以在&互斥反正傳遞給其他一些功能,如:

void corrupt_it(pthread_mutex_t *p_mutex); 
void foo() { 
    static pthread_mutex_t mutex; 
    corrupt_it(&mutex); 
} 
2

當地互斥鎖的一段代碼在一個線程。另一個線程也會鎖定它。還有下一個。但他們都不知道其他鎖。所以,如果你使用本地方法,你將實現大部分線程安全。

4

什麼是mutex

它是一個對象,用於通過多個線程訪問程序資源,但任何時候只有一個線程可以訪問資源。我認爲您不必從互斥角度考慮安全問題,因爲一旦鎖定,只有鎖定它的線程才能解鎖它。

所以你要麼互斥全局,要麼是靜態的,但從來不是局部的。

+1

在我眼中,現在是最清晰,最短,最尖銳的答案。加一。 – icbytes

0

如果你把它放在本地,它的範圍將是本地的。該函數的每個實例都有自己的小本地互斥鎖,與其他連接無關。

相關問題