Linux pthread_create的問題

各位LINX的前輩 大家好,

小弟目前正剛在學習LINUX,

而目前有遇到一些問題:

問題1:假如同時建立3個pthread_create,那這3個pthread_create是同步進行的嗎?

問題2:假如是為同步進行的話,那是否可以分成固定時間(如:1毫秒/5毫秒/10毫秒)去做這3個pthread_create的程式段?

問題3:假如可以分成固定時間的話,那不知道程式要如何撰寫?

希望各位前輩可以多多的指教.

感恩.

3 個解答

評分
  • 其威
    Lv 7
    1 0 年前
    最佳解答

    1. 不是, pthread_create() 是根據你呼叫 pthread_create() 那個 thread 的執行順序執行.

    例如你有三個 thread, 然後呼叫 pthread_create() 建立三個 thread

    #include <stdio.h>

    #include <stdlib.h>

    #include <pthread.h>

    void print_message_function( void *ptr );

    main()

    {

    pthread_t t1, t2, t3;

    char *message1 = "Hello";

    char *message2 = "World";

    char *message3 = "!";

    pthread_create( &t1, NULL, (void*)&print_message_function, (void*) message1);

    pthread_create( &t2, NULL, (void*)&print_message_function, (void*) message2);

    pthread_create( &t3, NULL, (void*)&print_message_function, (void*) message3);

    pthread_join( t1, NULL );

    pthread_join( t2, NULL );

    pthread_join( t3, NULL );

    printf("\n");

    exit(0);

    }

    void print_message_function( void *ptr )

    {

    printf("%s ", (char *)ptr);

    }

    這三個 thread 一定是先建立 t1, 再建立 t2, 最後建立 t3.

    但是三個 print_message_function 是 "同步" 執行的, 例如你可能會得到 "Hello World ! " 或 "! Hello World " 或 "Hello ! World " 或 "World ! Hello " 或... 懶的打了 = =

    甚至, 如果你的 message 夠長, 也許會得到 "HelWorld l! o " 這種結果...

    不過由於 pthread_create() 的成本通常很低 (低到你感覺不出來, 在我的系統上低於 clock_gettime() 的最低解析度), 所以如果三個 pthread_create() 是連在一起執行, 看起來的確很像 "同時建立了三個 thread".

    2. 如果你要讓 t1 在 1ms 的時候 create, t2 在 5ms 的時候 create, t3 在 10ms 的時候 create, 必須自己暫停.

    3.

    #include <stdio.h>

    #include <stdlib.h>

    #include <unistd.h>

    #include <pthread.h>

    void print_message_function( void *ptr );

    main()

    {

    pthread_t t1, t2, t3;

    char *message1 = "Hello";

    char *message2 = "World";

    char *message3 = "!";

    usleep(1000);

    pthread_create( &t1, NULL, (void*)&print_message_function, (void*) message1);

    usleep(4000); // 1000 + 4000 = 5000 = 5ms

    pthread_create( &t2, NULL, (void*)&print_message_function, (void*) message2);

    usleep(5000); // 1000 + 4000 + 5000 = 10000 = 10ms

    pthread_create( &t3, NULL, (void*)&print_message_function, (void*) message3);

    pthread_join( t1, NULL );

    pthread_join( t2, NULL );

    pthread_join( t3, NULL );

    printf("\n");

    exit(0);

    }

    void print_message_function( void *ptr )

    {

    printf("%s ", (char*)ptr);

    }

    2011-01-31 09:11:22 補充:

    1. usleep() 在 unistd.h 裡面. man usleep

    2. 這... linux 不是單晶片, 他是多工的系統啊... 你如果一定要取得從程式開始執行到現在為止的時間, 可以用 clock_gettime() 配合 CLOCK_PROCESS_CPUTIME_ID (這是 high resolution 的 timer), 如果平台不支援請用 CLOCK_MONOTONIC 或 CLOCK_REALTIME.

    CLOCK_PRECESS_CPUTIME_ID 速度最快而且解析度高, 然後是 MONOTONIC, 最慢的是 REALTIME.

    2011-01-31 09:14:32 補充:

    3. 你所謂 "連續運行" 是什麼意思?

    你要一直等它... 放進迴圈裡面跑吧...

    while (1)

    {

    pthread_create(t1, NULL, (void*)func, (void*)data);

    pthread_create(t2, NULL, (void*)func, (void*)data);

    pthread_join(t1, NULL);

    pthread_join(t2, NULL);

    }

    打不下, 請自己補上 t3 t4 t5 t6...

    2011-01-31 13:00:39 補充:

    沒錯, 這一切都要看 kernel schedular 怎麼分配 cputime 給你.

    不過, 現在的 kernel 用的 schedular (CFS), 如果你 JobA 啟動以後又經過 4ms 排不到 cpu (這幾乎不太可能), 那麼有下一個空的 cputime 的時候, 它會傾向分給 JobA 而不是 JobB.

    不過只是傾向, 不是絕對. 真實的狀況中, 你只能預期 kernel 會分配 cputime 給你, 但是不能預期它什麼時候會分配真的給你. 除非你手動調整該 thread 的 priority, 例如透過 sched_get_priority_max 特地要求.

    2011-02-01 20:37:05 補充:

    時間本來就不會很精確, 因為

    - linux 本來就不是 realtime OS

    - 還要考慮系統排程

    請問你需要多精確的計時?

    在我的系統上, 計時本身可以精確到 1ns, 但是暫停 (sleep) 就不一定了 (我搞不清楚他的精度是多少)

    2011-02-03 11:45:11 補充:

    首先要考慮你的硬體設備的能耐, 然後要考慮軟體的部份.

    你可能需要 real time. 如果是 linux, 可以用 rtlinux:

    http://www.kernel.org/pub/linux/kernel/projects/rt...

    但是 linux 的 realtime 不是 hard realtime:

    http://www.kernel.org/pub/linux/kernel/projects/rt...

    你的問題已經脫離原本的 pthread, 變成 realtime linux 了.

    如果還有進一步的問題, 請重新發問.

  • 是我
    Lv 5
    1 0 年前

    假設

    void* ThreadA(void* p) { return JobA(); }

    void* ThreadB(void* p) { return JobB(); }

    void* ThreadC(void* p) { return JobC(); }

    雖然

    1st ms:pthread_create(..., ThreadA, ...);

    5th ms:pthread_create(..., ThreadB, ...);

    10th ms:pthread_create(..., ThreadC, ...);

    執行順序仍有可能為:

    JobC

    JobB

    JobA

  • 1 0 年前

    非常感謝前輩的仔細指導,

    但就以前輩的語法來說,小弟有遇到幾個問題

    1.以useelp(x)函式,我找不到這個函式,只有seelp(x),是否還要做什麼#include 檔?

    2.以一個pthread_create的程式段做為1個固定時間去運行,如1ms or 5 ms or 10ms,但必須要包含運行的時間,因為小弟之前是使用單晶片,所以是以時間計數做為觸發1ms or 5 ms or 10ms的方式去做這3個程式段

    3.pthread_join()是否只會運行1次,是否有可以連續運行的函式?

    2011-01-31 09:34:07 補充:

    小弟在此感謝前輩熱心的指導,

    小弟會實作運行測試,

    謝謝您.

    感恩.

    2011-02-01 14:03:20 補充:

    在此先感謝各位前輩熱心的指導,

    所以想要請教各位前輩們:

    1.使用clcok_gettimg()做前和後時間的差異做時間(1ms & 5ms & 10ms)的判斷,但是實際運行並不是每次都是很固定,這是因為沒有real timeH的OS而導致的嗎?

    2011-02-01 14:04:48 補充:

    2.程式段:

    clock_gettime(CLOCK_REALTIME, &tt);

    Be = tt.tv_nsec;

    .

    .

    .

    .

    2011-02-01 14:05:15 補充:

    clock_gettime(CLOCK_REALTIME, &tt);

    Af = tt.tv_nsec;

    if((Af-Be) < 0) { Tal = (1000000000+Af)-Be; }

    else { Tal = Af-Be; }

    2011-02-01 14:07:22 補充:

    3.3段程式都是相同,只是內容不相同

    4.請各位前輩多多的指導

    5.恩感呢

    2011-02-01 14:13:22 補充:

    clock_gettime(CLOCK_REALTIME, &tt);

    Af= tt.tv_nsec;

    if((Af-Be) < 0) { Tal= (1000000000+Af)-Be; }

    else { Tal= Af-Be; }

    2011-02-01 14:13:32 補充:

    while(Tal< 5000000)

    {

    clock_gettime(CLOCK_REALTIME, &tt);

    AfTimerN = tt.tv_nsec;

    if ((Af-Be) < 0) { Tal= (1000000000+Af)-Be; }

    else { Tal= Af-Be; }

    }

    printf("Normal %d\\n",Tal);

    2011-02-03 06:13:50 補充:

    先跟各位前輩說聲~新年快樂~好運連連連~

    時間計時必須要精確的,

    因為小弟所做的系統是為控制使用,

    所以必要時可能要精度到0.1ms,

    時間誤差是必須要在0.1ms的0.001%內(有屬於時間計時使用),

    還請各位前輩多多的指導,

    感恩.

還有問題?馬上發問,尋求解答。