理解線程3 c語言示例線程基本操做

基本線程的動做

繼續以前C語言線程的文章:文章1 文章2 來了解基本的線程操做。html

設置線程屬性

設置脫離狀態

下面代碼中關鍵的地方在於:python

  • 經過 res = pthread_attr_init(&thread_attr); 初始化一個線程屬性編程

  • 經過 res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); 將屬性設置爲脫離狀態(PTHREAD_CREATE_DETACHED),即不能經過調用 pthread_join 來得到另外一個線程的退出狀態segmentfault

  • 另外還有一個經常使用的默認狀態是 PTHREAD_CREATE_JOINABLE ,能夠容許兩個線程從新合併。多線程

  • 屬性用完後對其進行清理回收 (void)pthread_attr_destroy(&thread_attr);框架

  • 經過共享的變量 thread_finished 來檢測子線程是否已經結束函數

代碼以下:線程

#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;

  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);
}

設置調度屬性

線程庫提供如下調度策略:設計

| SCHED_FIFO  | 先進先出 (FIFO) 調度。每一個線程都有一個固定的優先級;當多個線程具備相同的優先級時,它們按照先進先出 (FIFO) 的順序運行直到完成 |
| SCHED_RR    | 循環 (RR) 調度。每一個線程都有固定的優先級;當多個線程具備相同的優先級時,它們按照先進先出 (FIFO) 的順序在一個 固定的時間片內運行。 |
| SCHED_OTHER | 缺省的 AIX® 調度。每一個線程都有一個由調度程序根據線程的活動動態修改的初始優先級;線程的執行是按時間分割的。在其餘系統上,這個調度策略可能會不一樣。 |

設置調度屬性和設置很類似:code

#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;
    pthread_attr_t thread_attr;

    int max_priority;
    int min_priority;
    struct sched_param scheduling_value;

    res = pthread_attr_init(&thread_attr);
    if (res != 0) {
        perror("Attribute creation failed");
        exit(EXIT_FAILURE);
    }
    res = pthread_attr_setschedpolicy(&thread_attr, SCHED_OTHER);
    if (res != 0) {
        perror("Setting schedpolicy 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);
    }
    max_priority = sched_get_priority_max(SCHED_OTHER);
    min_priority = sched_get_priority_min(SCHED_OTHER);
    scheduling_value.sched_priority = min_priority;
    res = pthread_attr_setschedparam(&thread_attr, &scheduling_value);
    if (res != 0) {
        perror("Setting schedpolicy 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);
}

取消線程

  • 經過 int pthread_cancel(pthread_t thread); 來請求一個線程終止

  • 經過 int pthread_setcancelstate(int state, int *oldstate) 來設置接受的進程是容許取消請求仍是忽略它

  • 經過 int pthread_setcanceltype(int type, int *oldtype) 來設置取消類型, PTHREAD_CANCEL_ASYCHRONOUS 表明接收到取消請求後當即行動, THREAD_CANCEL_DEFERRED 表示在接收到請求後,等待函數執行下述動做之一後才取消線程: pthread_join, pthread_cond_wait, pthread_cond_timeout, pthread_test_cancel, sem_wait, sigwait

代碼以下:

#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("Caceling 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;
  res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  if (res != 0) {
    perror("Thread pthread_setcalcelstate 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 <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 6

void *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);
}

運行結果以下:

thread_function is running. Argument was 0
Bye from 0
thread_function is running. Argument was 1
thread_function is running. Argument was 2
Bye from 1
thread_function is running. Argument was 3
thread_function is running. Argument was 4
thread_function is running. Argument was 5
Waiting for threads to finish...
Bye from 5
Picked up a thread
Bye from 3
Bye from 2
Bye from 4
Picked up a thread
Picked up a thread
Picked up a thread
Picked up a thread
Picked up a thread
All done

瞭解更多

參考資料

PS

不得不認可,我失敗了。曾計劃天天分享一篇python相關知識點但沒有作到。失敗的緣由想找能夠找不少好比最近在作一個小的項目、這幾天出去聚會沒有時間、工做出現問題加班到比較晚等等,然而總結起來不外乎在內心它的重要程度是怎麼樣的。我反思了下幾乎作到一天一篇的這一個月過程作出改變,再也不要求一天一篇,而是當我有好的素材要分享時才分享,這樣與我與你們都是一件好事,我能夠動態調度本身的精力和注意力,好比最近實現了一半的一個odoo項目依賴關係分析器能夠儘快把它作完,對於讀者來講也能夠減小干擾看到更好的分享而不是像我以前有幾篇那樣划水的。但每週應該會有3-4篇Python的知識能夠分享。另外我目前的工做是基於Odoo的,我計劃嘗試作一些基礎的教程來分享這個我熟悉的框架,若是有進展必定會告知感興趣的讀者。感謝讀者。

最後向漩渦鳴人致敬,朝他的「說到作到,這就是個人忍道」努力。

相關文章
相關標籤/搜索