# Linux系統怎么創建線程
## 1. 線程的基本概念
### 1.1 什么是線程
線程(Thread)是操作系統能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位。一個進程可以包含多個線程,這些線程共享進程的資源(如內存空間、文件描述符等),但每個線程擁有獨立的程序計數器、寄存器集合和??臻g。
與進程相比,線程的創建和切換開銷更小,通信更方便(因為共享內存空間),因此在現代操作系統中被廣泛使用。
### 1.2 線程與進程的區別
| 特性 | 進程 | 線程 |
|--------------|--------------------------|--------------------------|
| 資源分配 | 獨立的內存空間 | 共享進程的內存空間 |
| 創建開銷 | 較大 | 較小 |
| 通信方式 | 管道、消息隊列、共享內存等 | 直接讀寫共享變量 |
| 上下文切換 | 開銷大 | 開銷小 |
| 獨立性 | 一個進程崩潰不影響其他進程 | 一個線程崩潰可能導致整個進程終止 |
## 2. Linux線程實現方式
### 2.1 LinuxThreads
早期的Linux線程實現,現在已經基本被NPTL取代。主要特點:
- 每個線程對應一個獨立的進程ID
- 信號處理存在問題
- 性能較差
### 2.2 NPTL (Native POSIX Threads Library)
現代Linux系統默認使用的線程實現(自Linux 2.6起):
- 真正的1:1線程模型(每個用戶線程對應一個內核線程)
- 高性能設計
- 更好的信號處理
- 完全兼容POSIX標準
可以通過命令查看系統使用的線程實現:
```bash
getconf GNU_LIBPTHREAD_VERSION
POSIX線程(pthread)是IEEE制定的線程標準接口,Linux通過NPTL實現了這一標準。使用pthread需要包含頭文件<pthread.h>
,并在編譯時鏈接-lpthread
庫。
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
參數說明:
- thread
: 用于存儲新線程ID的指針
- attr
: 線程屬性,NULL表示默認屬性
- start_routine
: 線程執行的函數
- arg
: 傳遞給線程函數的參數
返回值:成功返回0,失敗返回錯誤碼
線程可以通過以下方式終止:
1. 從線程函數中return
2. 調用pthread_exit()
3. 被其他線程取消(pthread_cancel()
)
void pthread_exit(void *retval);
int pthread_join(pthread_t thread, void **retval);
int pthread_detach(pthread_t thread);
pthread_join()
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
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_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_destroy(pthread_cond_t *cond);
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
pthread_attr_t attr;
pthread_attr_init(&attr);
// 設置分離狀態
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// 設置棧大小
size_t stacksize = 1024*1024; // 1MB
pthread_attr_setstacksize(&attr, stacksize);
// 設置調度策略
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
// 使用屬性創建線程
pthread_create(&thread, &attr, start_routine, arg);
// 銷毀屬性對象
pthread_attr_destroy(&attr);
struct sched_param param;
param.sched_priority = 50;
pthread_attr_setschedparam(&attr, ¶m);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
線程安全函數是指在多線程環境下能夠正確執行的函數,通常通過以下方式實現: - 不使用全局或靜態變量 - 使用互斥鎖保護共享數據 - 使用線程局部存儲
可重入函數是線程安全函數的子集,特點: - 不依賴全局或靜態變量 - 不調用不可重入函數 - 不使用靜態數據結構
pthread_key_t key;
void destructor(void *value) {
free(value);
}
pthread_key_create(&key, destructor);
void *value = malloc(100);
pthread_setspecific(key, value);
void *data = pthread_getspecific(key);
static __thread int tls_var;
取消點是線程檢查是否被取消的位置,包括:
- 顯式調用pthread_testcancel()
- 某些阻塞系統調用(如read、write、sleep等)
int oldtype;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
pthread_kill()
)pthread_sigmask()
)pthread_sigmask(SIG_BLOCK, &set, NULL);
int sig;
sigwait(&set, &sig);
typedef struct {
pthread_t *threads;
int thread_count;
task_queue_t queue;
pthread_mutex_t lock;
pthread_cond_t cond;
int shutdown;
} thread_pool_t;
void *worker_thread(void *arg) {
thread_pool_t *pool = (thread_pool_t *)arg;
while (1) {
pthread_mutex_lock(&pool->lock);
while (queue_empty(&pool->queue) && !pool->shutdown) {
pthread_cond_wait(&pool->cond, &pool->lock);
}
if (pool->shutdown) {
pthread_mutex_unlock(&pool->lock);
pthread_exit(NULL);
}
task_t task = queue_pop(&pool->queue);
pthread_mutex_unlock(&pool->lock);
task.function(task.arg);
}
return NULL;
}
gdb
調試多線程程序(info threads
,thread <id>
)strace -f
跟蹤線程系統調用#include <stdio.h>
#include <pthread.h>
void *print_hello(void *arg) {
printf("Hello from thread!\n");
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, print_hello, NULL);
pthread_join(thread, NULL);
return 0;
}
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int count = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *producer(void *arg) {
for (int i = 0; i < 20; i++) {
pthread_mutex_lock(&mutex);
while (count == BUFFER_SIZE) {
pthread_cond_wait(&cond, &mutex);
}
buffer[count++] = i;
printf("Produced: %d\n", i);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
usleep(100000);
}
return NULL;
}
void *consumer(void *arg) {
for (int i = 0; i < 20; i++) {
pthread_mutex_lock(&mutex);
while (count == 0) {
pthread_cond_wait(&cond, &mutex);
}
int item = buffer[--count];
printf("Consumed: %d\n", item);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
usleep(200000);
}
return NULL;
}
int main() {
pthread_t prod, cons;
pthread_create(&prod, NULL, producer, NULL);
pthread_create(&cons, NULL, consumer, NULL);
pthread_join(prod, NULL);
pthread_join(cons, NULL);
return 0;
}
可能原因:
- 資源限制(ulimit -u
查看用戶線程限制)
- 內存不足
- 達到系統線程數上限
解決方案:
- 檢查errno
值
- 調整系統限制(/etc/security/limits.conf
)
預防措施:
- 按固定順序獲取多個鎖
- 使用pthread_mutex_trylock()
- 設置鎖超時
優化方向: - 減少鎖競爭 - 使用線程局部存儲 - 考慮無鎖算法
#include <iostream>
#include <thread>
void thread_function() {
std::cout << "Hello from thread!\n";
}
int main() {
std::thread t(thread_function);
t.join();
return 0;
}
std::async
異步任務std::future
獲取異步結果std::promise
設置異步結果std::atomic
)Linux系統通過POSIX線程庫(pthread)提供了強大的多線程編程支持。創建線程的基本步驟包括:
1. 定義線程函數
2. 創建線程屬性(可選)
3. 調用pthread_create()
4. 管理線程生命周期(join/detach)
5. 使用同步機制保護共享數據
在多線程編程中,正確性比性能更重要。務必注意線程安全、避免競爭條件和死鎖?,F代C++也提供了更高級的線程抽象,可以根據項目需求選擇合適的工具。
通過合理使用多線程,可以顯著提高程序性能,特別是在多核CPU上。但同時也要注意線程帶來的復雜性,在簡單場景下,單線程配合事件驅動模型可能是更好的選擇。 “`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。