簡體   English   中英

使由函數初始化的變量可用於多線程環境中的函數

[英]Make a variable that is initialized by a function available to a function in multithreaded environment

所以這是我要解決的問題,我正在用C編程。

我們有一個可以為您初始化結構的函數。

typedef struct {
  int val1;
  int val2;
} custom_t;

custom_t init_custom() {
  custom_t temp;

  temp.val1 = 5;
  temp.val2 = 5;


  return temp;
}

您將像這樣使用它:

custom_t some_name = init_custom();

我有4個函數將custom_t用作輸入,並且可以使用它做一些工作。

在另一個文件中,我有很多庫函數將在多線程環境中運行。 無論線程如何,這些庫函數都需要在同一個custom_t變量上工作。

庫函數不會傳遞給custom_t變量,因為目標是另一個用戶應該能夠使用庫函數而無需考慮custom_t變量。

我在想我必須在定義庫函數的名稱空間中將custom_t變量設置為全局變量,但是出現一個錯誤,指出全局變量必須為const。

我不確定如何實現這一目標,我將不勝感激。 如果我的解釋不夠好,請隨時提出任何問題,我將盡力闡述。

編輯:修復了變量初始化錯誤

使用custom_t = init_custom(); 您正在嘗試設置類型名稱 (即custom_t )。

只是稱呼其他:

custom_t my_global_custom = init_custom();

但是,要從多個線程和庫函數訪問此函數,假設需要對其進行寫入,則需要將該訪問權包裝在互斥體中:

pthread_mutex_t custom_mutex = PTHREAD_MUTEX_INITIALIZER;
custom_t my_global_custom;

my_global_custom = init_custom();

// how each thread must access it
pthread_mutex_lock(&custom_mutex);
func_that_uses_my_global_custom();
pthread_mutex_unlock(&custom_mutex);

更新:

我的示例並不是從字面上看初始化程序,而是一個賦值

pthread_mutex_t custom_mutex = PTHREAD_MUTEX_INITIALIZER;
custom_t my_global_custom;
custom_t my_global_2;

custom_t
init_custom(void)
{
    custom_t temp;

    temp.val1 = 5;
    temp.val2 = 5;

    return temp;
}

void
init_custom2(custom_t *temp)
{

    temp->val1 = 5;
    temp->val2 = 5;
}

int
main(void)
{

    // either one of these should work ..
    my_global_custom = init_custom();
    init_custom2(&my_global_2);

    // start some threads ...

    return 0;
}

void *
thread_func(void *)
{

    // how each thread must access it:
    pthread_mutex_lock(&custom_mutex);
    func_that_uses_my_global_custom();
    pthread_mutex_unlock(&custom_mutex);

    return (void *) 0;
}

更新#2:

但是您知道在主函數之外初始化my_global_custom的任何方法嗎? 還是那不可能?

[至少在gcc下]的另一種方法是創建構造函數。 根據上述功能和定義,將init調用移至:

void __attribute__((constructor))
my_global_constructor(void)
{

    my_global_custom = init_custom();
    init_custom2(&my_global_2);
}

沒有什么需要[並沒有什么 ]調用此函數。 它會在調用main 之前自動被調用,因為它現在是一個特殊功能。

這些通常用於那些希望做一些初始化庫,但希望負擔 main有不必知道調用(如) init_liba(); init_libb(); ... init_liba(); init_libb(); ... init_liba(); init_libb(); ...在這種情況下,它在庫的“正確”時間被調用(基於鏈接等)。

還有一個__attribute__((destructor))可以用來“破壞”事物[在main返回之后,IIRC]。

有關更多信息,請參見: __attribute __((constructor))到底如何工作?

就個人而言,我現在使用上述屬性,但是出於懷舊之情,我喜歡舊的.init/.fini部分。

正如您對@CraigEstey的答案所做的評論所闡明的那樣,問題不在於變量不必為const ,而是其初始值設定項必須為編譯時常量。 解決此類問題的一種方法是通過宏而不是函數返回值來定義靜態初始化值。 例如,在一些適當的頭文件中聲明

typedef struct {
    int val1;
    int val2;
} custom_t;

#define CUSTOM_T_INITIALIZER { .val1 = 5, .val2 = 5 }

然后,您可以像這樣初始化custom_t類型的變量:

custom_t some_name = CUSTOM_T_INITIALIZER;

,包括文件范圍內的。

更新:

如果您需要為文件范圍或靜態持續時間變量分配一個非編譯時常量的值(包括其具有聚合類型並且其成員之一所需的值不是編譯時常量),那么您將無法為此使用初始化程序。 相反,您必須安排在程序啟動后將所需的值分配給該變量,可能是通過調用某種初始化函數來實現的。

暫無
暫無

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

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