Linux--編程--線程__html5

來源:互聯網
上載者:User
問題產生:

進程之間切換需求資源大,時間長,尋找一種更好的方法,出現線程。

新進程和新線程的區別:新進程擁有自己PID、變數、時間獨立、執行獨立。新線程擁有自己棧(即擁有自己的局部變數)、但它與建立者共用PID、全域變數、訊號處理函數、目前的目錄狀態等。 線程過程:

必須定義宏_REENTRANT並且依賴於pthread.h標頭檔,編譯時間使用-lpthread選項。   線程屬性:

  最重要的兩個是:

#include <pthread.h>int pthreed_attr_init(pthread_attr_t *attr);int pthread_attr_destroy(pthread_attr_t*attr);

還有其他的一些,自己百度,通過各種線程屬性函數可設定如脫離狀態、線程調度等。

  程式碼範例:

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <pthread.h>void *thread_function(void *arg);char message[] = "Hello World";int thread_finished = 0;int main() {    int res;    pthread_t a_thread;    void *thread_result;    pthread_attr_t thread_attr;    res = pthread_attr_init(&thread_attr);//屬性初始化    if (res != 0) {        perror("Attribute creation failed");        exit(EXIT_FAILURE);    }    res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);//允許無需對線程重新合并    if (res != 0) {        perror("Setting detached attribute failed");        exit(EXIT_FAILURE);    }//建立線程    res = pthread_create(&a_thread, &thread_attr, thread_function, (void *)message);    if (res != 0) {        perror("Thread creation failed");        exit(EXIT_FAILURE);    }    (void)pthread_attr_destroy(&thread_attr);//屬性清理回收    while(!thread_finished) {        printf("Waiting for thread to say it's finished...\n");        sleep(1);    }    printf("Other thread finished, bye!\n");    exit(EXIT_SUCCESS);}//線程函數void *thread_function(void *arg) {    printf("thread_function is running. Argument was %s\n", (char *)arg);    sleep(4);    printf("Second thread setting finished flag, and exiting now\n");    thread_finished = 1;    pthread_exit(NULL);}

  線程過程       建立線程:

#include <pthread.h>int pthread_creat(pthread_t*thread,pthread_attr_t *attr,void *(*start_routine)(void *),void *arg);

參數1:線程被建立時,該指標指向的變數中將被寫入一個標識符以來引用新線程。

參數2:用於設定線程屬性。如不需要特殊屬性可設定NULL。

參數3:傳遞線程函數本體。

參數4:傳遞線程函數參數。

傳回值:成功返回0,錯誤返回錯誤碼。

看一下線程函數:void*thread_function(void *arg);//注意這裡的void *     等待線程:

#include <pthread.h>int pthread_join(pthread-t th,void **thread_return);

參數1:要等待的線程,為pthread_creat第一個參數的返回標識符。

參數2:一個二級指標,最終指向某線程的傳回值。

傳回值:成功返回0,錯誤返回錯誤碼。

注意:程式中如果沒有此函數,主程式就會很快結束而導致線程沒有時間開始就結束。該函數本質上是以阻塞式等待thread指定的線程結束以最後回收線程資源。區別於該函數的是另一種線程----脫離線程。

對於一個二級指標可以這樣使用:

void *thread_result;res = pthread_join(a_thread,&thread_result);

    終止線程:

#include <pthread.h>void pthread_exit(void *retval);

    取消線程:

#include <pthread.h>int pthread_cancle(pthread_t thread);//很簡單,不再多說int pthread_setcanclestate(int stat,int*oldstat);

參數1:取值可以是PTHREAD_CANCLE_ENABLE,該值允許線程接收取消請求。取值還可以是PTHREAD_CANCLE_DISABLE,作用是忽略取消請求。

參數2:用於擷取先前的取消狀態,如果不想用可設定為NULL。

int pthread_setcancletype(int type,int*oldtype);

參數1:取值可以是PTHREAD_CANCLE_ASYNCHRONOUS,作用是接收到取消請求後立即執行,還可以是PTHREAD_CANCLE_DEFEREED,作用是不立即執行,直到執行到下列函數後才採取行動:pthread_join、pthread_cond_wait、pthread_cond_timedwait、pthread_testcancle、sem_wait或sigwait。

參數2:用於擷取先前的取消狀態,如果不想用可設定為NULL。預設情況下,線程在啟動時的取消狀態為PTHREAD_CANCLE_ENABLE,取消類型為PTHREAD_CANCLE_DEFREED。   程式碼範例:

1、 不帶取消線程的代碼:

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <pthread.h>void *thread_function(void *arg);char message[] = "Hello World";int main() {    int res;    pthread_t a_thread;    void *thread_result;    res = pthread_create(&a_thread, NULL, thread_function, (void *)message);//建立線程    if (res != 0) {        perror("Thread creation failed");        exit(EXIT_FAILURE);    }    printf("Waiting for thread to finish...\n");    res = pthread_join(a_thread, &thread_result);//等待線程    if (res != 0) {        perror("Thread join failed");        exit(EXIT_FAILURE);    }    printf("Thread joined, it returned %s\n", (char *)thread_result);    printf("Message is now %s\n", message);    exit(EXIT_SUCCESS);}void *thread_function(void *arg) {    printf("thread_function is running. Argument was %s\n", (char *)arg);    sleep(3);    strcpy(message, "Bye!");    pthread_exit("Thank you for the CPU time");//退出線程}

2、 帶取消線程的代碼:

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <pthread.h>void *thread_function(void *arg);int main() {    int res;    pthread_t a_thread;    void *thread_result;    res = pthread_create(&a_thread, NULL, thread_function, NULL);//建立線程    if (res != 0) {        perror("Thread creation failed");        exit(EXIT_FAILURE);    }    sleep(3);    printf("Canceling thread...\n");    res = pthread_cancel(a_thread);//取消線程的實施    if (res != 0) {        perror("Thread cancelation failed");        exit(EXIT_FAILURE);    }    printf("Waiting for thread to finish...\n");    res = pthread_join(a_thread, &thread_result);//等待線程    if (res != 0) {        perror("Thread join failed");        exit(EXIT_FAILURE);    }    exit(EXIT_SUCCESS);}//線程函數void *thread_function(void *arg) {    int i, res, j;    res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);//設定取消屬性狀態    if (res != 0) {        perror("Thread pthread_setcancelstate failed");        exit(EXIT_FAILURE);    }    res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);//設定取消屬性類型    if (res != 0) {        perror("Thread pthread_setcanceltype failed");        exit(EXIT_FAILURE);    }    printf("thread_function is running\n");    for(i = 0; i < 10; i++) {        printf("Thread is still running (%d)...\n", i);        sleep(1);    }    pthread_exit(0);//退出線程}

線程同步:

  訊號量

類似於唯一門口檢查員

#include <semaphore.h>//初始化訊號量int sem_init(sem_t *sem,intpshared,unsigned int value);//控制訊號量int sem_wait(sem_t * sem);//類似於P原子操作,-1int sem_post(sem_t * sem);//類似於V原子操作,+1//清理訊號量int sem_destroy(sem_t * sem);

sem_init()函數參數解釋:

參數1:指向的訊號量指標。

參數2:控制訊號量類型,值為0時表示該訊號量是當前進程的局部訊號量,否則這個訊號量就可以在多個進程之間共用。

所有函數成功返回0。

程式碼範例:

 

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include <semaphore.h>void *thread_function(void *arg);sem_t bin_sem;#define WORK_SIZE 1024char work_area[WORK_SIZE];int main() {    int res;    pthread_t a_thread;    void *thread_result;    res = sem_init(&bin_sem, 0, 0);    if (res != 0) {        perror("Semaphore initialization failed");        exit(EXIT_FAILURE);    }    res = pthread_create(&a_thread, NULL, thread_function, NULL);    if (res != 0) {        perror("Thread creation failed");        exit(EXIT_FAILURE);    }    printf("Input some text. Enter 'end' to finish\n");    while(strncmp("end", work_area, 3) != 0) {        fgets(work_area, WORK_SIZE, stdin);        sem_post(&bin_sem);    }    printf("\nWaiting for thread to finish...\n");    res = pthread_join(a_thread, &thread_result);    if (res != 0) {        perror("Thread join failed");        exit(EXIT_FAILURE);    }    printf("Thread joined\n");    sem_destroy(&bin_sem);    exit(EXIT_SUCCESS);}void *thread_function(void *arg) {    sem_wait(&bin_sem);    while(strncmp("end", work_area, 3) != 0) {        printf("You input %d characters\n", strlen(work_area) -1);        sem_wait(&bin_sem);    }    pthread_exit(NULL);}

  互斥量

類似於唯一門口保安員

#include <pthread.h>//初始化訊號量int pthread_mutex_init(pthread_mutex_t*mutex,const pthread_mutexattr_t *mutexattr);//鎖住資源int pthread_mutex_lock(pthread_mutex_t*mutex);//解鎖資源int pthread_mutex_unlock(pthread_mutex_t*mutex);//清理訊號量int pthread_mutex_destroy(pthread_mutex_t*mutex);

pthread_mutex_init()函數參數解釋:

參數1:指向的訊號量指標。

參數2:這裡略掉,自己百度。

所有函數成功返回0,失敗返回錯誤碼,但是這些函數並不設定error。

程式碼範例:

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include <semaphore.h>void *thread_function(void *arg);pthread_mutex_t work_mutex; /* protects both work_area and time_to_exit */#define WORK_SIZE 1024char work_area[WORK_SIZE];int time_to_exit = 0;int main() {    int res;    pthread_t a_thread;    void *thread_result;    res = pthread_mutex_init(&work_mutex, NULL);    if (res != 0) {        perror("Mutex initialization failed");        exit(EXIT_FAILURE);    }    res = pthread_create(&a_thread, NULL, thread_function, NULL);    if (res != 0) {        perror("Thread creation failed");        exit(EXIT_FAILURE);    }    pthread_mutex_lock(&work_mutex);    printf("Input some text. Enter 'end' to finish\n");    while(!time_to_exit) {        fgets(work_area, WORK_SIZE, stdin);        pthread_mutex_unlock(&work_mutex);        while(1) {            pthread_mutex_lock(&work_mutex);            if (work_area[0] != '\0') {                pthread_mutex_unlock(&work_mutex);                sleep(1);            }            else {                break;            }        }    }    pthread_mutex_unlock(&work_mutex);    printf("\nWaiting for thread to finish...\n");    res = pthread_join(a_thread, &thread_result);    if (res != 0) {        perror("Thread join failed");        exit(EXIT_FAILURE);    }    printf("Thread joined\n");    pthread_mutex_destroy(&work_mutex);    exit(EXIT_SUCCESS);}void *thread_function(void *arg) {    sleep(1);    pthread_mutex_lock(&work_mutex);    while(strncmp("end", work_area, 3) != 0) {        printf("You input %d characters\n", strlen(work_area) -1);        work_area[0] = '\0';        pthread_mutex_unlock(&work_mutex);        sleep(1);        pthread_mutex_lock(&work_mutex);        while (work_area[0] == '\0' ) {            pthread_mutex_unlock(&work_mutex);            sleep(1);            pthread_mutex_lock(&work_mutex);        }    }    time_to_exit = 1;    work_area[0] = '\0';    pthread_mutex_unlock(&work_mutex);    pthread_exit(0);}
問題解決:多線程程式碼範例:

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#define NUM_THREADS 6void *thread_function(void *arg);int main() {    int res;  pthread_t a_thread[NUM_THREADS];  void *thread_result;  int lots_of_threads;    for(lots_of_threads = 0; lots_of_threads < NUM_THREADS; lots_of_threads++) {    res = pthread_create(&(a_thread[lots_of_threads]), NULL, thread_function, (void *)lots_of_threads);    if (res != 0) {      perror("Thread creation failed");      exit(EXIT_FAILURE);    }    /*    sleep(1); */  }  printf("Waiting for threads to finish...\n");  for(lots_of_threads = NUM_THREADS - 1; lots_of_threads >= 0; lots_of_threads--) {    res = pthread_join(a_thread[lots_of_threads], &thread_result);    if (res == 0) {      printf("Picked up a thread\n");    } else {      perror("pthread_join failed");    }  }  printf("All done\n");    exit(EXIT_SUCCESS);}void *thread_function(void *arg) {    int my_number = (int)arg;    int rand_num;    printf("thread_function is running. Argument was %d\n", my_number);    rand_num=1+(int)(9.0*rand()/(RAND_MAX+1.0));    sleep(rand_num);    printf("Bye from %d\n", my_number);        pthread_exit(NULL);}

參考文檔:

Linux程式設計第四版    人民郵電出版社

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.