2012-10-08 101 views
2

我寫了一個C程序,使用兩個線程進行讀寫。我已經將這兩個線程都訪問的變量聲明爲Global。在這種情況下如何避免使用全局變量。如何避免在線程中使用全局變量

+0

作爲參數傳遞給線程函數的公共結構指針? –

+3

你可以看看Semaphores和Mutex,以便在不同線程中獨佔訪問共享全局變量。請讓我知道,如果你覺得這有用。如果這對你有用,我會發布這個答案。 – mihirj

+1

目前尚不清楚你想要什麼。你是不是想要全局變量?你不希望在其他線程中看到對這些變量的更改嗎?您是否希望更改在其他線程中可見,但以安全可控的方式顯示? –

回答

3

爲避免在這種情況下使用全局變量。

沒有必要避免全局變量。唯一需要考慮的是通過某種鎖定機制的有效數據。

將所有全局變量放入一個結構中是爲了在項目增長時進行可讀性和代碼控制。

我建議你使用互斥鎖。這是一個修改後的示例代碼。

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


typedef struct 
{ 
    double  *a; 
    double  *b; 
    double  sum; 
    int  veclen; 
} DOTDATA; 

/* Define globally accessible variables and a mutex */ 

#define NUMTHRDS 4 
#define VECLEN 100 
    DOTDATA dotstr; 
    pthread_t callThd[NUMTHRDS]; 
    pthread_mutex_t mutexsum; 


void *dotprod(void *arg) 
{ 

    /* Define and use local variables for convenience */ 

    int i, start, end, len ; 
    long offset; 
    double mysum, *x, *y; 
    offset = (long)arg; 

    len = dotstr.veclen; 
    start = offset*len; 
    end = start + len; 
    x = dotstr.a; 
    y = dotstr.b; 

    /* 
    Perform the dot product and assign result 
    to the appropriate variable in the structure. 
    */ 

    mysum = 0; 
    for (i=start; i<end ; i++) 
    { 
     mysum += (x[i] * y[i]); 
    } 

    /* 
    Lock a mutex prior to updating the value in the shared 
    structure, and unlock it upon updating. 
    */ 
    pthread_mutex_lock (&mutexsum); 
    dotstr.sum += mysum; 
    pthread_mutex_unlock (&mutexsum); 

    pthread_exit((void*) 0); 
} 

/* 
The main program creates threads which do all the work and then 
print out result upon completion. Before creating the threads, 
the input data is created. Since all threads update a shared structure, 
we need a mutex for mutual exclusion. The main thread needs to wait for 
all threads to complete, it waits for each one of the threads. We specify 
a thread attribute value that allow the main thread to join with the 
threads it creates. Note also that we free up handles when they are 
no longer needed. 
*/ 

int main (int argc, char *argv[]) 
{ 
    long i; 
    double *a, *b; 
    void *status;  

    /* Assign storage and initialize values */ 
    a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double)); 
    b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double)); 

    for (i=0; i<VECLEN*NUMTHRDS; i++) 
    { 
    a[i]=1.0; 
    b[i]=a[i]; 
    } 

    dotstr.veclen = VECLEN; 
    dotstr.a = a; 
    dotstr.b = b; 
    dotstr.sum=0; 

    pthread_mutex_init(&mutexsum, NULL);    

    for(i=0; i<NUMTHRDS; i++) 
    { 
     /* 
     Each thread works on a different set of data. 
     The offset is specified by 'i'. The size of 
     the data for each thread is indicated by VECLEN. 
     */ 
     pthread_create(&callThd[i], NULL, dotprod, (void *)i); 
    } 

    /* Wait on the other threads */ 
    for(i=0; i<NUMTHRDS; i++) 
    { 
     pthread_join(callThd[i], &status); 
    } 

    /* After joining, print out the results and cleanup */ 
    printf ("Sum = %f \n", dotstr.sum); 
    free (a); 
    free (b); 
    pthread_mutex_destroy(&mutexsum); 
    pthread_exit(NULL); 
} 
1
  1. 如果您希望每個線程都有單獨的變量副本,請將變量聲明爲線程局部變量。
1

您可以製作結構。我通常使用一個名爲globalArgs的結構,我把所有那裏的全局變量。

事情是這樣的:

static typedef struct { 
int foo; 
int baa; 
} globalargs; 

或者,您可以通過所有值作爲參數傳遞給需要的功能。

4

請考慮使用C pthread庫下面的方法對具有用C共享全局變量的獨佔訪問:

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); 
int pthread_mutex_lock(pthread_mutex_t *mutex); 
int pthread_mutex_unlock(pthread_mutex_t *mutex); 
int pthread_mutex_destroy(pthread_mutex_t *mutex); 

同樣,你可以看看信號燈同步使用全局變量的使用C線程。

3

你真的需要一個共享變量,或者你真的需要每個線程的相同數據的2個副本嗎?如果是這樣,而不是聲明它是全局的,在創建時將它作爲參數傳遞給線程。

如果確實需要共享,則需要使用互斥體進行保護。如果將共享變量與互斥鎖一起綁定到結構中,並在創建時將它作爲參數傳遞給線程,則仍然可以廢除全局變量。

2

我想你問的是如何避免讓你的線程在啓動時通過傳遞他們的工作數據來訪問全局變量。

請參閱pthread_create的最後一個參數,它允許您定義一個用戶定義的自定義指針,該指針可以是任何您想要的。使用它可以傳遞數據(比如結構地址或者甚至是值),只要該值能夠適應平臺的空指針大小即可。

例如,家長可以通過做這樣發送一個子線程數據:

Data data; 
pthread_create(&thrd, NULL, threadProc, &data); 

孩子PROC會被引用此:

void *threadProc(void *pv) 
{ 
    Data *pData = (Data*)pv; 
    .. use data here... 
    pthread_exit(NULL); 
} 

我希望這是有道理的,並希望它可以幫助您瞭解如何將數據傳遞給線程處理程序,這是我的認爲您的問題是。