当前位置: 首页 > news >正文

5、linux c 线程 - 上

【四】线程

1. 线程的创建

#include <pthread.h>
​
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*routine)(void *), void *arg);
  • pthread_t *thread:指向线程标识符的指针,用于存储新创建线程的 ID。

  • const pthread_attr_t *attr:线程属性指针,通常传 NULL 使用默认属性。

  • void *(*routine)(void *):线程执行的函数指针,即线程开始执行的函数。

  • void *arg:传递给线程函数的参数,可以是任意类型,但需要正确转换。

返回值

  • 成功:返回 0。

  • 失败:返回非零错误码。

特点

  • 创建线程需要时间,如果主进程很快退出,线程可能无法执行。

  • 主进程退出时,其创建的所有线程也会随之退出。

示例代码

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
​
// 线程执行函数
void *thread_function(void *arg) {
    printf("Thread is running, TID: %lu\n", pthread_self());
    sleep(2);
    printf("Thread finished\n");
    return NULL;
}
​
int main() {
    pthread_t tid;
    int ret = pthread_create(&tid, NULL, thread_function, NULL);
    if (ret != 0) {
        perror("pthread_create failed");
        return 1;
    }
    printf("Main process, PID: %d\n", getpid());
    sleep(3); // 确保线程有时间运行
    return 0;
}

2. 线程的退出

pthread_exit

#include <pthread.h>
​
void pthread_exit(void *retval);
  • void *retval:线程的返回值,可以是任意类型,但需要正确转换。

特点

  • 调用 pthread_exit 可以使线程正常退出。

  • 主进程退出时,其创建的所有线程也会随之退出。

示例代码

#include <stdio.h>
#include <pthread.h>
​
// 线程执行函数
void *thread_function(void *arg) {
    printf("Thread is running, TID: %lu\n", pthread_self());
    sleep(2);
    printf("Thread finished\n");
    pthread_exit((void *)0); // 线程正常退出
    return NULL;
}
​
int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, thread_function, NULL);
    printf("Main process, waiting for thread...\n");
    sleep(3);
    return 0;
}

3. 获取线程 ID

pthread_self

#include <pthread.h>
​
pthread_t pthread_self(void);

特点

  • 返回当前线程的 ID。

  • 可以通过 pthread_create 的第一个参数获取线程 ID,也可以在线程内部调用 pthread_self 获取。

示例代码

#include <stdio.h>
#include <pthread.h>
​
// 线程执行函数
void *thread_function(void *arg) {
    printf("Thread is running, TID: %lu\n", pthread_self());
    return NULL;
}
​
int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, thread_function, NULL);
    printf("Main process, PID: %d\n", getpid());
    sleep(1);
    return 0;
}

4. 线程间参数传递

参数传递方式

pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*routine)(void *), void *arg);
  • 通过地址传递参数:注意类型的转换。

  • 值传递:编译器可能会告警,需要程序员自己保证数据长度正确。

示例代码

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
​
// 线程执行函数
void *thread_function(void *arg) {
    int num = *((int *)arg); // 转换为 int 类型
    printf("Thread is running, received number: %d\n", num);
    free(arg); // 释放分配的内存
    return NULL;
}
​
int main() {
    pthread_t tid;
    int *num = (int *)malloc(sizeof(int));
    *num = 42;
    pthread_create(&tid, NULL, thread_function, (void *)num);
    printf("Main process, sent number: %d\n", *num);
    sleep(1);
    return 0;
}

5. 线程的回收

pthread_join

#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);
  • pthread_t thread:要回收的线程 ID。

  • `void retval**:用于存储线程的返回值,可以是NULL`。

返回值

  • 成功:返回 0。

  • 失败:返回非零错误码。

特点

  • pthread_join 是阻塞函数,如果回收的线程未结束,则一直等待。

示例代码

#include <stdio.h>
#include <pthread.h>

// 线程执行函数
void *thread_function(void *arg) {
    printf("Thread is running, TID: %lu\n", pthread_self());
    sleep(2);
    printf("Thread finished\n");
    return (void *)0;
}

int main() {
    pthread_t tid;
    void *retval;
    pthread_create(&tid, NULL, thread_function, NULL);
    printf("Main process, waiting for thread...\n");
    int ret = pthread_join(tid, &retval);
    if (ret != 0) {
        perror("pthread_join failed");
        return 1;
    }
    printf("Thread exited with status: %ld\n", (long)retval);
    return 0;
}

6. 线程的分离

1、使用 pthread_detach

#include <pthread.h>

int pthread_detach(pthread_t thread);

2、创建线程时设置分离属性

#include <pthread.h>

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

特点

  • 分离线程在退出时会自动回收资源,无需显式调用 pthread_join

示例代码

#include <stdio.h>
#include <pthread.h>

// 线程执行函数
void *thread_function(void *arg) {
    printf("Thread is running, TID: %lu\n", pthread_self());
    sleep(2);
    printf("Thread finished\n");
    return NULL;
}

int main() {
    pthread_t tid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    pthread_create(&tid, &attr, thread_function, NULL);
    printf("Main process, PID: %d\n", getpid());
    sleep(3);
    return 0;
}
  1. 查看线程

ps -eLf | grep [名字]


文章转载自:

http://o1BTE2jS.kLrpm.cn
http://88RuelXF.kLrpm.cn
http://dyCe2Cvt.kLrpm.cn
http://yC76TNmD.kLrpm.cn
http://SlUFEB86.kLrpm.cn
http://jNKkjEDQ.kLrpm.cn
http://tmNWFzmw.kLrpm.cn
http://zKAsZDeN.kLrpm.cn
http://v8WQnuwu.kLrpm.cn
http://zXHzLDLq.kLrpm.cn
http://EqAoK29F.kLrpm.cn
http://bQPo5H0r.kLrpm.cn
http://mfepR7e7.kLrpm.cn
http://HhjoSHG7.kLrpm.cn
http://ZEZBbM9d.kLrpm.cn
http://g7fXMLve.kLrpm.cn
http://2zf0tIu5.kLrpm.cn
http://gO8w0wZO.kLrpm.cn
http://FOAzY63Y.kLrpm.cn
http://P2c2BaLG.kLrpm.cn
http://sG4mNchj.kLrpm.cn
http://Qcofifvo.kLrpm.cn
http://CSXM0B7w.kLrpm.cn
http://V8iCMB8N.kLrpm.cn
http://pPNp5srP.kLrpm.cn
http://vSvbf1JB.kLrpm.cn
http://sRwlsdLm.kLrpm.cn
http://ccgtosuy.kLrpm.cn
http://HP8qhMYR.kLrpm.cn
http://4zI8IAQ9.kLrpm.cn
http://www.dtcms.com/a/85979.html

相关文章:

  • 基于STM32的两路电压测量仿真设计Proteus仿真+程序设计+设计报告+讲解视频
  • 使用LVS的 NAT 模式实现 3 台RS的轮询访问
  • (学习总结30)Linux 进程优先级、进程切换和环境变量
  • 使用LLM 构建MCP服务端和客户端
  • 信息安全和病毒防护——防火墙的作用
  • SFT和RLHF是什么意思?
  • Axure项目实战:智慧城市APP(四)医疗信息(动态面板、选中交互应用)
  • Jboss中间件漏洞攻略
  • java学习笔记6
  • 【云馨AI-大模型】大模型的开发和应用中,Python、PyTorch和vLLM关系概括
  • 从扩展黎曼泽塔函数构造物质和时空的结构-1
  • netty框架概述
  • 蓝桥云客 合并数列
  • 01、聊天与语言模型
  • [python]IsaacGym安装
  • 多线程编程
  • Android应用退出后不在任务栏显示
  • 如何做好需求管理培训
  • Rk3588,Opencv读取Gmsl相机,Rga yuv422转换rgb (降低CPU使用率)
  • 2.1.1~2词法分析的手工构造
  • 判断一个操作是不是允许
  • 3.23学习总结
  • 运筹优化梳理
  • [M模拟] lc2116. 判断一个括号字符串是否有效(思维+括号匹配问题+问题分析+代码实现)
  • 交换机远程登录
  • 基于Python的智慧金融风控系统的设计与实现
  • 银河麒麟桌面版包管理器(五)
  • 计算机操作系统(五) 前趋图和程序执行与进程的描述(附带图谱表格更好对比理解))
  • MySQL 死锁问题分析与解决方案
  • 机房布局和布线的最佳实践:如何打造高效、安全的机房环境