Linux下創建線程

一、線程的概念

線程是指進程內部的一個執行單元,也稱為輕量級進程,它和進程一樣可以獨立執行、擁有獨立的棧空間、程序計數器和寄存器等,但是多個線程可以共享進程的資源,如內存空間、文件、I/O。線程的創建和銷毀都比進程更加的輕便快捷,因此多線程成為了提高系統性能和程序效率的一種重要方式。

二、線程的創建

Linux提供了幾種方式創建線程:pthread_create()、clone()等。其中pthread_create()是比較常用的一個函數,其函數原型如下:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

它的參數依次為:

1、指向線程標識符的指針;

2、線程屬性,NULL表示使用默認屬性;

3、指向函數的指針,該函數是新線程的入口地址;

4、函數的參數。

下面是一個簡單的例子:

#include 
#include 
#include 

void *print_message_function(void *ptr);

int main()
{
    pthread_t thread1, thread2;
    char *message1 = "Thread 1";
    char *message2 = "Thread 2";
    int ret1, ret2;

    // 創建線程1
    ret1 = pthread_create(&thread1, NULL, print_message_function, (void *) message1);
    if (ret1 != 0)
    {
        printf("Create thread 1 failed!\n");
        exit(1);
    }

    // 創建線程2
    ret2 = pthread_create(&thread2, NULL, print_message_function, (void *) message2);
    if (ret2 != 0)
    {
        printf("Create thread 2 failed!\n");
        exit(1);
    }

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    printf("Main function exits!\n");
    return 0;
}

void *print_message_function(void *ptr)
{
    char *message = (char *) ptr;
    printf("%s\n", message);
}

在上面的例子中,我們使用pthread_create()函數創建了2個線程,並傳入一個字符串作為線程函數的參數。然後使用pthread_join()函數等待線程結束。

三、線程的同步

線程之間的同步通常需要互斥量、條件變量等機制。比如常用的互斥量pthread_mutex_t可以用來保護共享資源,pthread_cond_t則可以用來進行線程的條件等待與喚醒。

下面是一個使用互斥量保護共享資源的例子:

#include 
#include 
#include 

#define THREAD_NUM 5

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int sum = 0;

void *thread_function(void *arg);

int main()
{
    pthread_t threads[THREAD_NUM];

    // 創建多個線程
    for (int i = 0; i < THREAD_NUM; i++)
    {
        pthread_create(&threads[i], NULL, thread_function, NULL);
    }

    // 等待所有線程結束
    for (int i = 0; i < THREAD_NUM; i++)
    {
        pthread_join(threads[i], NULL);
    }

    printf("Sum = %d\n", sum);
    return 0;
}

void *thread_function(void *arg)
{
    int i;
    for (i = 0; i < 1000; i++)
    {
        pthread_mutex_lock(&mutex);
        sum++;
        pthread_mutex_unlock(&mutex);
    }

    pthread_exit(NULL);
}

在這個例子中,我們使用pthread_mutex_t來保護sum這個共享資源,多個線程會去累加這個值。由於多個線程同時訪問sum,如果沒有互斥保護,會產生競爭狀態,導致結果不正確。因此我們使用互斥量對共享資源進行保護,保證線程之間的同步。

四、線程的銷毀

線程的銷毀通常是在線程函數中通過pthread_exit()函數進行,也可以使用pthread_cancel()函數強製取消線程。同時可以使用pthread_join()函數等待線程結束,防止進程過早退出,導致線程沒有執行完畢。

下面是一個使用pthread_cancel()函數強製取消線程的例子:

#include 
#include 
#include 

void *thread_function(void *arg);

int main()
{
    pthread_t thread_id;
    int ret;

    // 創建線程
    ret = pthread_create(&thread_id, NULL, thread_function, NULL);
    if (ret != 0)
    {
        printf("Create thread failed!\n");
        exit(1);
    }

    // 睡眠 5 秒
    sleep(5);

    // 強制殺死線程
    pthread_cancel(thread_id);

    printf("Main function exits!\n");
    return 0;
}

void *thread_function(void *arg)
{
    int i;

    // 設置取消狀態
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

    // 設置取消類型
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

    for (i = 0; ; i++)
    {
        printf("Thread running...\n");
        sleep(1);
    }

    pthread_exit(NULL);
}

在上面的例子中,我們使用了pthread_cancel()函數強製取消線程。同時在線程函數中設置了取消狀態和取消類型。

五、線程的屬性

線程的屬性可以用來調整線程的優先級、棧大小等。pthread_attr_t是線程屬性的類型,Linux提供了一些函數來進行線程屬性的設置和獲取,如pthread_attr_init()、pthread_attr_setstacksize()、pthread_attr_getschedpolicy()等。

下面是一個設置線程棧大小的例子:

#include 
#include 
#include 

void *thread_function(void *arg);

int main()
{
    pthread_t thread_id;
    pthread_attr_t attr;
    size_t stacksize;
    int ret;

    // 初始化線程屬性
    pthread_attr_init(&attr);
    pthread_attr_getstacksize(&attr, &stacksize);
    printf("Default stack size = %d KB\n", (int) stacksize / 1024);

    // 設置線程棧大小
    pthread_attr_setstacksize(&attr, 1024 * 1024);
    pthread_attr_getstacksize(&attr, &stacksize);
    printf("New stack size = %d KB\n", (int) stacksize / 1024);

    // 創建線程
    ret = pthread_create(&thread_id, &attr, thread_function, NULL);
    if (ret != 0)
    {
        printf("Create thread failed!\n");
        exit(1);
    }

    // 等待線程結束
    pthread_join(thread_id, NULL);

    printf("Main function exits!\n");
    return 0;
}

void *thread_function(void *arg)
{
    int i;

    for (i = 0; i < 10; i++)
    {
        printf("Thread running...\n");
        sleep(1);
    }

    pthread_exit(NULL);
}

在上面的例子中,我們使用了pthread_attr_setstacksize()函數設置了線程的棧大小為1MB。

六、總結

本文介紹了Linux下創建線程的方法及相關知識。具體來說,我們講解了線程的概念、創建、同步、銷毀和屬性等內容。通過本文的學習,讀者可以掌握如何使用Linux提供的相關函數來創建線程,並進行進一步的開發。

原創文章,作者:TOOK,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/143334.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
TOOK的頭像TOOK
上一篇 2024-10-14 18:47
下一篇 2024-10-14 18:47

相關推薦

  • Python線程等待指南

    本文將從多個方面詳細講解Python線程等待的相關知識。 一、等待線程結束 在多線程編程中,經常需要等待線程執行完畢再進行下一步操作。可以使用join()方法實現等待線程執行完畢再…

    編程 2025-04-29
  • Python兩個線程交替打印1到100

    這篇文章的主題是關於Python多線程的應用。我們將會通過實際的代碼,學習如何使用Python兩個線程交替打印1到100。 一、創建線程 在Python中,我們可以使用Thread…

    編程 2025-04-28
  • ROS線程發布消息異常解決方法

    針對ROS線程發布消息異常問題,我們可以從以下幾個方面進行分析和解決。 一、檢查ROS代碼是否正確 首先,我們需要檢查ROS代碼是否正確。可能會出現的問題包括: 是否正確初始化RO…

    編程 2025-04-28
  • Python線程池並發爬蟲

    Python線程池並發爬蟲是實現多線程爬取數據的常用技術之一,可以在一定程度上提高爬取效率和數據處理能力。本文將從多個方面對Python線程池並發爬蟲做詳細的闡述,包括線程池的實現…

    編程 2025-04-27
  • 如何在Linux中添加用戶並修改配置文件

    本文將從多個方面詳細介紹在Linux系統下如何添加新用戶並修改配置文件 一、添加新用戶 在Linux系統下創建新用戶非常簡單,只需使用adduser命令即可。使用以下命令添加新用戶…

    編程 2025-04-27
  • 如何解決linux jar包 invalid or corrupt jarfile問題

    對於許多開發人員和系統管理員在Linux環境下使用Java開發過程中遇到的一個常見的問題是 invalid or corrupt jarfile(無效或損壞的jar文件)錯誤。當您…

    編程 2025-04-27
  • 線程池中的一個線程異常了會被怎麼處理

    本文將從以下幾個方面對線程池中的一個線程異常了會被怎麼處理進行詳細闡述:異常的類型、如何捕獲異常、異常的處理方式。 一、異常的類型 在線程池中,可以出現多種類型的異常,例如線程執行…

    編程 2025-04-27
  • 在Linux上安裝JRE並配置環境變量

    本文將從以下幾個方面為您詳細闡述如何在Linux系統上,通過自己賬戶安裝JRE,並且配置環境變量。 一、安裝JRE 在進行安裝前,我們需要下載JRE的安裝包並解壓,可以從官方網站下…

    編程 2025-04-27
  • GTKAM:Linux下的照片管理器

    GTKAM是用於Linux操作系統的一款照片管理器,它支持多種相機及存儲設備,並提供了一系列強大的工具,讓用戶可以方便地瀏覽、管理、編輯和導出照片。本文將從多個方面對GTKAM進行…

    編程 2025-04-27
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁盤中。在執行sync之前,所有的文件系統更新將不會立即寫入磁盤,而是先緩存在內存…

    編程 2025-04-25

發表回復

登錄後才能評論