0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux下线程编程

wang123a 来源:嵌入式技术 作者:嵌入式技术 2022-08-24 15:42 次阅读

Linux下线程编程

1.线程相关函数

 1.1创建线程pthread_create

  pthread_create是Unix操作系统(Unix、linux等)的创建线程的函数。
  注:编译时需要指定链接库 -lpthread
  函数原型:

#include 
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
形参: thread — 指向线程标志符的指针类型为:pthread_t *
  attr — 设置线程属性,默认填NULL。类型为:const pthread_attr_t *
  void *(*start_routine) (void *) — 函数指针,现在运行函数的起始地址
  arg — 运行函数的参数。不需要填NULL ,类型为:void *
返回值: 成功返回0;失败返回错误编号。
  线程创建成功后,attr参数用于指定线程属性,新创建的线程函数形参只有一个void *形参,若需要传入的参数不止一个,则可以把需要传入的参数保存到一个结构体中,通过结构体传入。

  示例:

#include 
#include 
#include 
void *start_routine_func(void *arg)
{
    while (1)
    {
      printf("子线程运行中。。。\n");
      sleep(1);
    } 
}
int main()
{
    int stat;
    pthread_t pth;//线程标志符
    pthread_create(&pth,NULL,start_routine_func,NULL);
    while(1)
    {
        printf("主线程运行中。。。\n");
        sleep(1);
    }
}
[xsw@xsw 系统编程]$ gcc pthread.c -l pthread
[xsw@xsw 系统编程]$ ./a.out 
主线程运行中。。。
子线程运行中。。。
主线程运行中。。。
子线程运行中。。。
子线程运行中。。。
主线程运行中。。。

 1.2 退出线程pthread_exit

  函数原型:

void pthread_exit(void *retval);
函数功能:
  终止调用它的线程并通过形参返回一个指向某个对象的指针
形 参: void *retval — 线程需要返回的地址
返回值: 无
  注:线程结束必须释放线程堆栈,也就是线程函数必须调用pthread_exit()结束,否则直到主进程函数退出才释放。

  示例:

#include 
#include 
#include 
void *start_routine_func(void *arg)
{
    int cnt=0;
    while (1)
    {
      printf("子线程运行中cnt=%d。。。\n",cnt);
      sleep(1);
      cnt++;
      if(cnt>=3)break;
    } 
    pthread_exit(NULL);//退出线程,释放堆栈
    
}
int main()
{
    int stat;
    pthread_t pth;//线程标志符
    /*创建子线线程*/
    if(pthread_create(&pth,NULL,start_routine_func,NULL)!=0)
    {
        printf("线程创建失败\n");
        return 0;
    }
    printf("子线程ID=%lu\n",pth);
    /*等待线程退出*/
    pthread_join(pth,NULL);
    printf("线程退出成功\r\n");
    return 0;
}
[xsw@xsw 系统编程]$ gcc pthread.c -lpthread
[xsw@xsw 系统编程]$ ./a.out 
子线程ID=3078433648
子线程运行中cnt=0。。。
子线程运行中cnt=1。。。
子线程运行中cnt=2。。。
线程退出成功

 1.3 等待线程结束pthread_join

int pthread_join(pthread_t thread, void **retval);
函数功能:
  以阻塞方式等待thread指定线程结束,当函数返回值,被等待线程的资源被回收。若线程已经结束,则立即返回。并且thread指定的线程必须是joinable(结合属性)属性。
形 参: thread — 线程标志符(线程ID)。线程唯一标志,类型为:pthread_t
  retval — 用户定义的指针,用来存储被等待线程返回的地址
返回值: 成功返回0,失败返回错误编号。

  示例:

#include 
#include 
#include 
void *start_routine_func(void *arg)
{
    int cnt=0;
    while (1)
    {
      printf("子线程运行中cnt=%d。。。\n",cnt);
      sleep(1);
      cnt++;
      if(cnt>=3)break;
    } 
    pthread_exit(NULL);//退出线程,释放堆栈
    
}
int main()
{
    int stat;
    pthread_t pth;//线程标志符
    /*创建子线线程*/
    if(pthread_create(&pth,NULL,start_routine_func,NULL)!=0)
    {
        printf("线程创建失败\n");
        return 0;
    }
    printf("子线程ID=%lu\n",pth);
    /*等待线程退出*/
    pthread_join(pth,NULL);
    printf("线程退出成功\r\n");
    return 0;
}
[xsw@xsw 系统编程]$ gcc pthread.c -lpthread
[xsw@xsw 系统编程]$ ./a.out 
子线程ID=3078433648
子线程运行中cnt=0。。。
子线程运行中cnt=1。。。
子线程运行中cnt=2。。。
线程退出成功

 1.4 获取当前线程标志符pthread_self

  函数原型:

pthread_t pthread_self(void);
函数功能:
  获取线程自身ID。
形 参: 无
返回值: 返回当前线程标志符。pthread_t类型为unsigned long int,打印应%lu。

  示例:

#include 
#include 
#include 
void *start_routine_func(void *arg)
{
    printf("子线程ID=%lu运行中。。。\n",pthread_self());
    pthread_exit(NULL);//退出线程,释放堆栈
}
int main()
{
    int stat;
    int i=0;
    pthread_t pth;//线程标志符
    printf("主线程ID=%lu\n",pthread_self());
    /*创建5个子线线程*/
    for(i=0;i<5;i++)
    {
        if(pthread_create(&pth,NULL,start_routine_func,NULL)!=0)
        {
            printf("线程创建失败\n");
            return 0;
        }
        printf("子线程ID=%lu\n",pth);
    }
    /*等待线程退出*/
    pthread_join(pth,NULL);
    printf("线程退出成功\r\n");
    return 0;
}
[xsw@xsw 系统编程]$ gcc pthread.c -lpthread
[xsw@xsw 系统编程]$ ./a.out 
主线程ID=3078706880
子线程ID=3078703984
子线程ID=3068214128
子线程ID=3057724272
子线程ID=3047234416
子线程ID=3036744560
子线程ID=3068214128运行中。。。
子线程ID=3078703984运行中。。。
子线程ID=3057724272运行中。。。
子线程ID=3047234416运行中。。。
子线程ID=3036744560运行中。。。
线程退出成功

 1.5 自动清理线程资源

  函数原型:

//注册清理函数
void pthread_cleanup_push(void (*routine)(void *),void *arg);
//释放清理函数
void pthread_cleanup_pop(int execute);
函数功能:
  线程清除处理函数,用于程序异常退出的时候做善后的资源清理。自动释放资源。
  注:pthread_cleanup_push函数与pthread_cleanup_pop函数需要成对调用。
形 参:
  void (*routine)(void *) — 处理程序函数入口
  void *arg — 传递给处理函数形参
  int execute — 执行的状态值,0 – 不调用清理函数;1 – 调用清理函数。
返回值: 无
导致调用清理函数条件:
  1.调用pthread_exit()函数
  2.Pthread_claenup_pop的形参为1
  注:return不会导致清理函数调用。

  示例:

#include 
#include 
#include 
/*线程清理函数*/
void routine_Clinen(void *arg)
{
    printf("arg=%d\n",*(int *)arg);
    free(arg);
    printf("释放空间完成\n");
}
/*子线程函数*/
void *start_routine_func (void *arg)
{
    printf("arg=%s,线程运行中...\n",arg);
    char *p=malloc(4);
    *p=100;
    //注册线程清理函数
    pthread_cleanup_push(routine_Clinen,p);
    pthread_exit("子线程返回数据测试!");//释放线程堆栈
   // return 0;//return终止不会触发线程清理函数
    //调用线程清理函数
    pthread_cleanup_pop(1);
}
int main() 
{
    /*1.创建线程*/
    char buff[]="线程传入参数测试";
    pthread_t thread;
    if(pthread_create(&thread,NULL,start_routine_func,buff)!=0)
    {
        printf("线程创建失败\n");
        return 0;
    }
    printf("线程ID=%lu\n",pthread_self());
    char *p;
    pthread_join(thread,(void **)&p);//等待线程退出
    printf("子线程返回数据:%s\n",p);
    printf("主线程退出\n");
    return 0;
}
[xsw@xsw 系统编程]$ gcc pthread.c -lpthread
[xsw@xsw 系统编程]$ ./a.out 
arg=线程传入参数测试,线程运行中...
线程ID=3078866624
arg=100
释放空间完成
子线程返回数据:子线程返回数据测试!
主线程退出

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    10987

    浏览量

    206723
  • 函数
    +关注

    关注

    3

    文章

    3865

    浏览量

    61307
  • 线程
    +关注

    关注

    0

    文章

    488

    浏览量

    19495
  • 线程编程
    +关注

    关注

    0

    文章

    5

    浏览量

    6105
收藏 人收藏

    评论

    相关推荐

    Linux下线程编程(2)

    线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程
    的头像 发表于 08-24 15:48 1532次阅读

    Linux开发_采用线程处理网络请求

    介绍Linux下网络编程线程编程,select机制,利用子线程响应TCP服务器的请求。
    的头像 发表于 09-17 15:21 655次阅读

    Linux线程编程基础知识解析

    线程是轻量级的进程(`LWP: Light Weight Process`),在`Linux`环境下线程的本质仍是`进程`,进程是资源分配的`最小单位`,线程是操作系统调度执行的`最小
    发表于 07-14 16:41 470次阅读
    <b class='flag-5'>Linux</b>多<b class='flag-5'>线程</b><b class='flag-5'>编程</b>基础知识解析

    Linux线程编程手册

    Linux线程编程手册
    发表于 11-07 10:17

    嵌入式Linux线程编程

    嵌入式Linux线程编程-学习资源-华清远见清远见嵌入式学院:清远见嵌入式学院:《嵌入式应用程序设计》——第5 章 嵌入式Linux线程
    发表于 11-05 06:54

    如何对Linux系统多线程进行编程

    Linux系统编程第07期:多线程编程入门 6年嵌入式开发经验,在多家半导体...
    发表于 12-23 08:08

    linux线程编程课件

    电子发烧友为您提供了linux线程编程课件,希望对您学习 linux 有所帮助。部分内容如下: *1、多线程模型在单处理器模型和多处理器系
    发表于 07-10 11:58 0次下载

    linux线程编程开发

    本文中我们针对 Linux 上多线程编程的主要特性总结出 5 条经验,用以改善 Linux线程编程
    发表于 12-26 14:24 55次下载
    <b class='flag-5'>linux</b>多<b class='flag-5'>线程</b><b class='flag-5'>编程</b>开发

    线程编程Linux线程编程

    9.2 Linux线程编程 9.2.1 线程基本编程 这里要讲的线程相关操作都是用户空间中的
    发表于 10-18 15:55 3次下载

    Linux下的多线程编程

    的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。  下面我们先来尝试编写一个简单的多线程程序。2 简单的多线程编程  
    发表于 04-02 14:43 474次阅读

    嵌入式linux线程编程实验,嵌入式Linux线程编程-学习资源-华清远见.PDF

    嵌入式Linux线程编程-学习资源-华清远见清远见嵌入式学院:清远见嵌入式学院:《嵌入式应用程序设计》——第5 章 嵌入式Linux线程
    发表于 11-02 13:36 7次下载
    嵌入式<b class='flag-5'>linux</b>多<b class='flag-5'>线程</b><b class='flag-5'>编程</b>实验,嵌入式<b class='flag-5'>Linux</b>多<b class='flag-5'>线程</b><b class='flag-5'>编程</b>-学习资源-华清远见.PDF

    Linux下线程与进程的区别

    线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程
    的头像 发表于 08-24 15:37 1629次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>下线程</b>与进程的区别

    Linux中多线程编程的知识点

    Hello、Hello大家好,我是木荣,今天我们继续来聊一聊Linux中多线程编程中的重要知识点,详细谈谈多线程中同步和互斥机制。
    发表于 04-26 17:27 479次阅读
    <b class='flag-5'>Linux</b>中多<b class='flag-5'>线程</b><b class='flag-5'>编程</b>的知识点

    Linux线程线程与异步编程、协程与异步介绍

    线程之间的切换不需要陷入内核,但部分操作系统中用户态线程的切换需要内核态线程的辅助。 协程是编程语言(或者 lib)提供的特性(协程之间的切换方式与过程可以由
    的头像 发表于 11-11 11:35 422次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>线程</b>、<b class='flag-5'>线程</b>与异步<b class='flag-5'>编程</b>、协程与异步介绍

    linux线程编程实例

    linux线程
    的头像 发表于 02-15 21:16 69次阅读
    <b class='flag-5'>linux</b>多<b class='flag-5'>线程</b><b class='flag-5'>编程</b>实例