Vietnamese Developers’ Blog

POSIX Thread (2)

Posted in Unix/Linux/BSD by Hoang Tran on October 18, 2007

Chúng ta hãy bắt đầu bằng một ví dụ đơn giản.

thread1.c

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

void *thread_function(void *arg)
{
    int i;
    for ( i=0; i<20; i++ ) {
        printf("Thread says hi!\n");
        sleep(1);
    }

    return NULL;
}

int main(void)
{
    pthread_t mythread;

    if ( pthread_create( &mythread, NULL, thread_function, NULL) ) {
        printf("error creating thread.");
        abort();
    }

    printf(“Waiting for thread to finish...\n”);
    if ( pthread_join ( mythread, NULL ) ) {
        printf("error joining thread.");
        abort();
    }

    exit(0);
}

Biên dịch chương trình
$ gcc thread1.c -o thread1 -lpthread

thread1.c là một chương trình sử dụng thread rất đơn giản. Nó không thực sự làm gì hữu ích cả mà chỉ giúp chúng ta hiểu về cách thread làm việc.

Trong hàm main() chúng ta khai báo một biến là mythread có kiểu pthread_t. Kiểu pthread_t được định nghĩa trong pthread.h thường được gọi là thread id (viêt tắt là tid). Hãy nghĩ nó như là một dạng thread handle.

Sau khi mythread được khai báo (mythread chỉ là một “tid” hay một handle vào thread mà chúng ta sẽ khởi tạo), chúng ta gọi hàm pthread_create() để khởi tạo một thread thực sự. Hàm này sẽ trả về 0 nếu khởi tạo thread thành công và trả về một số khác 0 nếu thất bại. Hàm pthread_create có 4 tham số:

- tham số đầu tiên là một con trỏ tới mythread (&mythread),

- tham số thứ hai (trong chương trình được khởi tạo là NULL) có thể được sử dụng để xác định thuộc tính của thread. Vì thuộc tính mặc định của thread sử dụng tốt trong ví dụ của chúng ta nên chỉ đơn giản thiết lập nó là NULL,

- tham số thứ ba là tên của chương trình mà thread khởi tạo sẽ thực thi khi nó bắt đầu. Trong chương trình trên đó là hàm thread_function(). Khi hàm này trả về thì đồng nghĩa với việc thread mới sẽ dừng. Trong ví dụ trên thì nó chỉ đơn giản in ra “Thread says hi!” 20 lần và thoát ra. Chú ý rằng thread_function chấp nhận một con trỏ void* như là tham số và cũng trả về một trỏ void*. Có nghĩa là có thể truyền tham số cho thread mới và ở chương trình chính cũng có thể lấy được giá trị trả về của thread. Thế nhưng làm cách nào truyền tham số cho thread mới ở trong hàm pthread_create(). Nó được truyền ở

- tham số thứ tư của hàm pthread_create() dùng để truyền dữ liệu như là tham số thread mới. Trong ví dụ trên nó được khởi tạo NULL bởi vì chúng ta không cần truyền dữ liệu gì cho hàm thread_function().

Có thể thấy rằng ở chương trình trên bao gồm 2 threads sau khi hàm pthread_create() trả về thành công: một là thread mới tạo ra và một là thread của chương trình chính. Chương trình chính cũng được coi là một thread.

Sau khi thread mới được tạo ra thì thread chính vẫn tiếp tục thực thi lệnh tiếp theo trong chương trình (if ( pthread_join(…) )). Vì pthread_create tách thread chính thành 2 threads, nên pthread_join sẽ hợp 2 threads đó thành một. Tham số đầu tiên của pthread_join() là thread_id, mythread. Tham số thứ hai là một con trỏ trỏ vào một con trỏ void. Nếu con trỏ void không phải là NULL, thì pthread_join sẽ đặt giá trị trả về của thread_function (là một con trỏ void*) vào tham số thứ 2. Bởi vì trong ví dụ trên chúng ta không quan tâm về giá trị trả về của thead_function() nên chúng ta truyền vào NULL.

Hàm thread_function mất 20 giây để thực thi. Trước đó thì ở thread chính đã gọi pthread_join(), có nghĩa là thread chính đã bị block (sleep) và phải đợi thread_function() hoàn thành. Ngay khi thread_function kết thúc thì pthread_join() trả về. Lúc này thì chương trình chỉ còn thread chính. Khi chương trình kết thúc thì tất cả các thread mới sẽ phải được pthread_join.

Tham khảo: http://www.ibm.com/developerworks/linux/library/l-posix1.html?

Tagged with: , ,

2 Responses

Subscribe to comments with RSS.

  1. betasuka said, on December 20, 2007 at 3:15 am

    minh rat ung ho bai viet cua ban, tuy nhien, can phai them thu vien stdio vi ban su dung printf trong doan code nay, hon nua, neu ai do dung copy doan code nay, can chu y dau nhay kep trong printf, vi no co the ko tuong thich.

  2. Nguyen Vinh Phuc said, on June 27, 2008 at 10:49 am

    Sao em chạy trên thì nó báo thế này nhỉ. Error creating thread.Abort(coredump)


Leave a Reply