您好,登录后才能下订单哦!
# Linux系统怎么创建线程
## 1. 线程的基本概念
### 1.1 什么是线程
线程(Thread)是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程可以包含多个线程,这些线程共享进程的资源(如内存空间、文件描述符等),但每个线程拥有独立的程序计数器、寄存器集合和栈空间。
与进程相比,线程的创建和切换开销更小,通信更方便(因为共享内存空间),因此在现代操作系统中被广泛使用。
### 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. 使用同步机制保护共享数据
在多线程编程中,正确性比性能更重要。务必注意线程安全、避免竞争条件和死锁。现代C++也提供了更高级的线程抽象,可以根据项目需求选择合适的工具。
通过合理使用多线程,可以显著提高程序性能,特别是在多核CPU上。但同时也要注意线程带来的复杂性,在简单场景下,单线程配合事件驱动模型可能是更好的选择。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。