Linux软件编程(六)(exec 函数族、system 实现、进程回收与线程通信)
一、线程回收策略
在 Linux 中,线程创建后,结束时需要被回收,否则会变成“僵尸线程”,占用系统资源。
1.1 分离属性的线程
定义:不需要被其他线程回收的线程,称为分离属性线程。
特点:线程退出后由系统自动回收,不会变成僵尸线程。
设置方法:
#include <pthread.h>
int pthread_detach(pthread_t thread);
示例:
pthread_t tid; pthread_create(&tid, NULL, thread_func, NULL); pthread_detach(tid); // 设置为分离属性
1.2 非分离属性的线程(默认属性)
定义:需要被其他线程回收的线程(默认属性)。
特点:线程结束后不会立即释放资源,必须调用
pthread_join()
回收。使用方法:
pthread_t tid;
pthread_create(&tid, NULL, thread_func, NULL);
pthread_join(tid, NULL); // 阻塞等待,回收线程资源
1.3 注意事项
分离属性线程:不用
pthread_join()
,由系统自动回收。非分离属性线程:必须调用
pthread_join()
,否则会变成僵尸线程。
二、线程间通信
多线程之间需要共享数据时,常见方式是 全局变量。
但多个线程同时访问共享变量时会导致 资源竞争,需要使用 互斥机制。
2.1 临界资源
定义:多个线程可能同时访问的共享资源。
例子:全局变量、共享内存等。
2.2 互斥锁(mutex)
作用:保证任意时刻只有一个线程能访问临界资源。
相关函数:
pthread_mutex_t mutex; // 定义互斥锁
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);// 销毁
attr
:一般填NULL
,使用默认属性。加锁和解锁必须成对出现。
2.3 示例代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int counter = 0; // 全局变量(临界资源)
pthread_mutex_t mutex; // 定义互斥锁
void *thread_func(void *arg)
{
for (int i = 0; i < 5; i++)
{
pthread_mutex_lock(&mutex); // 加锁
counter++;
printf("Thread %ld: counter = %d\n", pthread_self(), counter); pthread_mutex_unlock(&mutex); // 解锁
sleep(1);
}
return NULL;
}
int main()
{
pthread_t t1, t2;
pthread_mutex_init(&mutex, NULL); // 初始化互斥锁
pthread_create(&t1, NULL, thread_func, NULL);
pthread_create(&t2, NULL, thread_func, NULL);
pthread_join(t1, NULL); // 回收线程
pthread_join(t2, NULL); pthread_mutex_destroy(&mutex); // 销毁锁
return 0;
}
三、总结
线程回收
分离属性线程:
pthread_detach()
,系统自动回收。非分离属性线程:默认,需要
pthread_join()
回收,否则会变僵尸线程。
线程通信
使用互斥锁
pthread_mutex_t
保护临界资源。pthread_mutex_lock()
和pthread_mutex_unlock()
必须成对出现。最后记得
pthread_mutex_destroy()
。