Linux 6
·
线程
线程是进程内部的一个执行单元,是CPU调度的最小单位。
线程是一个轻量级的进程,用来实现多任务并发。
线程是操作系统任务调度的最小单位。
线程由某个进程创建
-
线程的创建
线程由所在进程创建,创建时,进程为其分配独立的栈区空间(默认8M)。
同一个进程中的线程,共用所在进程的堆区、数据区、文本区。
-
线程的调度
宏观并行
微观串行
-
线程消亡
线程退出
回收线程的资源空间

pthread_create
POSIX 线程库中创建新线程的核心函数。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
thread |
pthread_t * |
输出 | 存储新线程的ID |
attr |
const pthread_attr_t * |
输入 | 线程属性,NULL=默认 |
start_routine |
void *(*)(void*) |
输入 | 线程要执行的函数 |
arg |
void * |
输入 | 传递给线程函数的参数 |
传入int型
#include <stdio.h>
#include <pthread.h>
void *thread_func(void *arg) {
int num = *(int *)arg; // 取出 int 值
printf("收到的整数: %d\n", num);
return NULL;
}
int main() {
pthread_t tid;
int value = 100;
// 传入 int 变量的地址
pthread_create(&tid, NULL, thread_func, &value);
pthread_join(tid, NULL);
return 0;
}
传入结构体
typedef struct task
{
pthread_t tid;// 成员1:线程ID
void *(*pfun)(void*);// 成员2:线程函数指针
}task_t;
/*task_t tasks[]=
{
{0, main_ctl_task},
{0, get_usr_cmd_task},
{0, exec_usr_cmd_task},
{0, get_pic_task},
{0, send_pic_task}
};*/
task_t tasks[]=
{
{.pfun=main_ctl_task},
{.pfun=get_usr_cmd_task},
{.pfun=exec_usr_cmd_task},
{.pfun=get_pic_task},
{.pfun=send_pic_task}
};//局部定义
int main(void)
{
create_thread_tasks(tasks,sizeof(tasks)/sizeof(tasks[0]));
destory_thread_tasks(tasks,sizeof(tasks)/sizeof(tasks[0]));
return 0;
}
#include<stdio.h>
#include<unistd.h>
#include"task.h"
int create_thread_tasks(task_t *tasks,int len)
{
for(int i=0;i<len;i++)
{
int ret = pthread_create(&(tasks[i].tid),NULL,tasks[i].pfun,NULL);
//
if(ret!=0)
{
fprintf(stderr,"error\n");
return -1;
}
}
return 0;
}
void destory_thread_tasks(task_t *tasks,int len)
{
for(int i=0;i<len;i++)
{
pthread_join(tasks[i].tid,NULL);
}
}
易错点
// ❌ 错误
void create() {
int local = 100;//开到栈上会自动销毁
pthread_create(&tid, NULL, thread_func, &local);
// local 在函数返回后销毁,线程可能访问无效内存
}
// ✅ 正确
void create() {
int *ptr = malloc(sizeof(int));
*ptr = 100;
pthread_create(&tid, NULL, thread_func, ptr);
// 线程负责 free
}
pthread_self
POSIX 线程库中用于获取当前线程ID的函数
void *thread_func(void *arg) {
// 获取当前线程(子线程)的ID
pthread_t tid = pthread_self();
printf("子线程ID: %lx\n", tid);
return NULL;
}
pthread_join(pthread_t thread, void **retval)
POSIX 线程库中用于等待指定线程结束并回收其资源的核心函数。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
thread |
pthread_t |
输入 | 要等待的线程ID |
retval |
void ** |
输出 | 接收线程返回值(可为 NULL) |
| 返回值 | 含义 |
|---|---|
0 |
成功 |
pthread_join(tid, NULL);
线程的分离属性
分离属性 :不需要被其他线程回收的线程,称为具有分离属性的线程,结束时可以被操作系统回收。
非分离属性:可以被其他线程回收或者结束的线程称为非分离属性的线程
默认属性:非分离属性

线程的互斥机制
多线程访问临界资源时,存在资源竞争问题。
临界资源:多个线程可以同时操作的资源,比如:全局变量,共享内存等。
如何解决资源竞争问题:
线程的互斥机制:让多个线程在访问临界资源时,具有排他性访问的特性
互斥锁:实现互斥机制
- 创建互斥锁:pthread_mutex_t
- 初始化锁:pthread_mutex_init
- 加锁:pthread_mutex_lock/pthread_mutex_trylock
- 解锁:pthread_mutex_unlock
- 销毁锁:pthread_mutex_destroy

注意锁的位置
int atm = 3;
pthread_mutex_t mutex;
void *task(void *arg)
{
while (1)
{
pthread_mutex_lock(&mutex);
if (atm > 0)
{
atm--;
printf("%lx thread get ATM\n", pthread_self());
pthread_mutex_unlock(&mutex);
sleep(rand()%10);
pthread_mutex_lock(&mutex);
atm++;
printf("%lx thread relase ATM\n", pthread_self());
pthread_mutex_unlock(&mutex);
return NULL;
}
else
{
pthread_mutex_unlock(&mutex);
}
}
}
int main(int argc, const char *argv[])
{
pthread_t tid[10];
pthread_mutex_init(&mutex, NULL);
for (int i = 0; i < 10; i++)
{
pthread_create(&tid[i], NULL, task, NULL);
}
for (int i = 0; i < 10; i++)
{
pthread_join(tid[i], NULL);
}
pthread_mutex_destroy(&mutex);
return 0;
}
更多推荐




所有评论(0)