簡體   English   中英

C語言與多線程編程

[英]C language and multithread programming

我的問題與 C 中的線程編程有關。

我的問題是我只想在我的main中創建兩個線程。 這兩個線程應該按順序工作,這意味着我的第一個線程應該首先執行(不應執行任何線程的其他語句)。 第一個線程應該有完全的控制權。 在第一個線程完成之前,不應執行任何其他線程的其他語句,甚至是main語句。

第一個線程完成后,第二個線程應該以與第一個線程類似的方式執行。

之后我的主要應該執行。

我知道你可以說我為什么要這樣做,因為這可以通過創建兩個函數並按順序調用它們來實現,但是為了學習和實驗,我想在線程的幫助下完成。

我在 C 中寫了一些代碼如下:

void* fun()
{  
    printf("\nThe thread 1 is running");
}
void* van()
{
    printf("\nthread 2 is running ");
}

int main()
{
    pthread_t t1,t2;
    pthread_create(&t1,NULL,fun,NULL);
    pthread_create(&t2,NULL,van,NULL);
    printf("\nI'm in main\n");
    pthread_join(t2,NULL); 
}

該程序運行良好,但我不理解 function pthread_join()的工作。

當我按如下方式更改我的代碼時:

int main()
{
    pthread_t t1,t2;
    pthread_create(&t1,NULL,fun,NULL);
    pthread_join(t2,NULL);  // Change
    pthread_create(&t2,NULL,van,NULL);
    printf("\nI'm in main\n");
}

現在,當我運行代碼時,它會顯示分段錯誤。

現在我的問題如下:

  1. pthread_create() function 中的屬性參數是什么? 我們為什么要使用它們? 線程的默認屬性是什么? 請舉例說明。
  2. pthread_create() function 中的參數是什么? 我們為什么要使用它們? 線程的默認 arguments 是什么? 請舉例說明。
  3. pthread_join()實際上是如何工作的? 當我的代碼以t2作為第一個參數在 main 中調用pthread_join()時,這是什么意思。 這是否意味着 main 應該暫停執行,直到 t2 執行完成或其他什么?
  4. pthread_join()中的第二個參數是什么? 我們為什么用它? 它的默認值是多少? 請用示例或代碼解釋。
  1. attr 參數指向一個 pthread_attr_t 結構,其內容在線程創建時用於確定新線程的屬性; 這個結構是使用pthread_attr_init(3)和相關函數初始化的。 如果 attr 是 NULL,則使用默認屬性 ( source ) 創建線程。

  2. 參數被傳遞給你的線程 function。 這是將數據傳遞給線程的最佳方式(與使用全局變量相反,例如)。

  3. 是的, pthread_join一直等到線程完成。 這就是為什么在啟動線程之前調用pthread_join時程序會失敗的原因,因為此時 t2 包含垃圾。

  4. 如果 retval 不是 NULL,則 pthread_join() 將目標線程的退出狀態(即目標線程提供給 pthread_exit(3) 的值)復制到 *retval 指向的位置。 如果目標線程被取消,則 PTHREAD_CANCELED 被放置在 *retval 中。 來源)。

即,您可以使您的線程 function 通知您其執行結果。

鑒於此,您的線程創建可能如下所示:

struct th_arg{
    ...
};

static void th_work(struct th_arg* a){
     //...some work
    if (success) pthread_exit(EXIT_SUCCESS)
    else pthread_exit(ERROR_CODE);
}

int main(){
     int t1,t2;
     struct th_arg[2];
     int codes[2];
     // initialize th_arg2 
     pthread_create(&t1, NULL, th_work, th_arg+0, th_arg+0);
     pthread_create(&t2, NULL, th_work, th_arg+1, th_arg+1);
     pthread_join(t1, codes+0);
     pthread_join(t2, codes+1);

     if (codes[0] == EXIT_SUCCESS && codes[1] == EXIT_SUCCESS){
             ...
     }
}  

學習 posix 線程的最佳來源是https://computing.llnl.gov/tutorials/pthreads/

  • pthread_attr_t中的屬性屬於pthread_create類型。 它保存有關線程的信息,包括線程的 memory 地址從哪里開始以及它的堆棧可以達到多大。 大多數情況下,您不需要使用此參數。

  • pthread_create中的 arg 作為唯一的參數傳遞給start_routine function。 這是一種黑客行為。 由於指針可以指向任何東西(int、數組、結構等),因此您可以通過將指針傳遞給您要傳入的所有數據來傳入 arguments。大多數時候人們最終會選擇一個結構。 線程沒有默認的 arguments。 如果您不想傳入任何內容,只需將arg指定為 NULL。

舉個例子:

struct arguments
{
    int something;
    char* anotherArg;
    short stillAnotherArg;
}

void* fun(void* arg)
{
    struct arguments *my_args = (struct arguments*)arg;
    printf("You said: %s\n", my_args->anotherArg); // Will print "You said: Hello there"
    ...
}

int main()
{
    pthread_t t1;

    struct arguments my_args;
    my_args.something = 5;
    my_args.anotherArg = "Hello there";
    my_args.stillAnotherArg = 42;

    pthread_create (&t1,NULL,fun, &my_args);
    ...
}
  • pthread_join阻塞調用者,直到指定的線程完成。

  • pthread_join的第二個參數允許您捕獲線程執行完成后的返回值。 您的每個線程都返回一個void* ,第二個參數允許您指定該返回值的存儲位置。

舉個例子:

void* fun(void* arg)
{
    ...
    return NULL; // not very exciting, but I don't want to get
                 // into memory management problems right now
}

int main()
{
    ...

    void* theReturnValue;
    pthread_join(t2, &theReturnValue);

    printf("fun returned %p\n", theReturnValue); // will print "fun returned 0x0"
                                                 // which is NULL
}

最后,它出現段錯誤的原因是因為您正在等待尚未定義的線程。

您可以通過包含omp.h來使用omp庫。 它很容易使用。 您可以使用指令創建並行部分

#pragma omp parallel
{
    // PARALLEL Code
}

並使用omp_set_num_threads(2); 然后使用omp_get_thread_num();

例子:

omp_set_num_threads(2);
#pragma omp parallel
{
    printf("thread %d said hello", omp_get_thread_num());
}

暫無
暫無

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

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