跨境派

跨境派

跨境派,专注跨境行业新闻资讯、跨境电商知识分享!

当前位置:首页 > 跨境学堂 > 【linux c多线程】线程的创建,线程信息的获取,获取线程返回值

【linux c多线程】线程的创建,线程信息的获取,获取线程返回值

时间:2024-03-24 11:42:53 来源:网络cs 作者:淼淼 栏目:跨境学堂 阅读:

标签: 获取  返回  信息  创建 
阅读本书更多章节>>>>

线程创建

专栏内容

参天引擎内核架构
本专栏一起来聊聊参天引擎内核架构,以及如何实现多机的数据库节点的多读多写,与传统主备,MPP的区别,技术难点的分析,数据元数据同步,多主节点的情况下对故障容灾的支持。

手写数据库toadb
本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。
本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段学习。

开源贡献

toadb开源库

个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

文章目录

线程创建前言概述线程介绍创建线程退出线程获取返回值线程信息示例代码总结结尾

前言

现代的CPU都是多core处理器,而且在intel处理器中每个core又可以多个processor,形成了多任务并行处理的硬件架构,在服务器端的处理器上架构又有一些不同,传统的采用SMP,也就是对称的多任务处理架构,每个任务都可以对等的访问所有内存,外设等,而如今在ARM系列CPU上,多采用NUMA架构,它将CPU核分了几个组,给每个组的CPU core分配了对应的内存和外设,CPU访问对应的内存和外设时速度最优,跨组访问时性能会降底一些。

随着硬件技术的持续发展,它们对一般应用的性能优化能力越来越强,同时对于服务器软件的开发,提出更高要求,要想达到极高的并发和性能,就需要充分利用当前硬件架构的特点,对它们进行压榨。那么,我们的应用至少也是要采用多任务架构,不管是多线程还是多进程的多任务架构,才可以充分利用硬件的资源,达到高效的处理能力。

当然多任务框架的采用,不仅仅是多线程的执行,需要对多任务下带来的问题进行处理,如任务执行返回值获取,任务间数据的传递,任务执行次序的协调;当然也不是任务越多处理越快,要避免线程过多导致操作系统夯住,也要防止任务空转过快导致CPU使用率飙高。

本专栏主要介绍使用多线程与多进程模型,如何搭建多任务的应用框架,同时对多任务下的数据通信,数据同步,任务控制,以及CPU core与任务绑定等相关知识的分享,让大家在实际开发中轻松构建自已的多任务程序。

概述

本文主要分享多线程的创建,退出,以及线程属性的设置,线程执行返回等相关posix API,以及流程。

在多任务架构搭建中,常常使用多线程方式,因为线程相较于进程,是一种轻量级的任务,也是最小的任务单元,还有一个关键点是,线程间的通信方式更加灵活和方便,相反的进程间通信就必须要借助内核手段。

线程的使用流程,主要包括线程的创建启动,线程的退出,线程任务返回值获取,线程信息的管理等几方面。

在linux中我们采用posix线程库进行介绍,在编译时需要增加 -lpthread,头文件需要包括 # include <pthread.h>

线程介绍

我们已经知道线程是一种轻量级的任务单元,它是在进程中创建,共享当前进程的内存上下文,也就是说线程是在进程的控制之下,进程不存在时,线程也就会退出,这就是“皮之不存,毛将焉附”。

另外一个重要特点是,线程的内存模型,同一进程中的所有线程共享当前进程的内存空间,这就是说不同线程对全局变量的修改,都是相互可以看到的,动态内存申请的内存也是可以相互传递的,同时局部静态变量也是共享的。

创建线程

在linux 创建线程,需要指定线程的描述符,线程的任务执行函数,以及它的入参,当然也可以对线程的属性进行设置。

创建线程的函数
#include <pthread.h>int pthread_create(pthread_t *restrict thread,                          const pthread_attr_t *restrict attr,                          void *(*start_routine)(void *),                          void *restrict arg);
参数说明
thread, 线程描述符,记录线程句标识;

attr, 线程属性,可以线程行为进行控制;

start_routine, 线程执行的主函数;声明格式为 void * func(void *pointer);

arg, 主函数的入参,因为主函数是由线程调度程序自动调用的,参数必须在创建时指定。

退出线程

线程的退出,可以通过以下几种方式:

start_routine 线程执行函数正常返回,如函数完成时执行return ;调用线程退出函数 pthread_exit, 这相当于执行函数提前退出;使用线程控制函数 pthread_cancel,让某一线程退出;线程所在的进程退出,或者调用exit,或者主函数main返回了,这都会导致该进程下的所有线程退出。

获取返回值

很多时候,线程执行结束后,都会带有返回值,调用者需要根据返回值决定任务执行的情况,如何获取线程执行函数的返回值呢?

同一进程下的各线程间的关系是平等的,只要知道了线程的标识后,调用下面的函数就可以获取对方的返回值。

#include <pthread.h>int pthread_join(pthread_t thread, void **retval);
参数说明
thread, 线程的标识,创建线程时会得到;

retval, 返回码;由pthread_exit或者return 返回;

函数说明

调用者调用此函数后会被阻塞,至到thread标识的线程返回为止。

线程信息

线程在创建以后,除了调用者可以获取线程标识外,线程本身也可以通过函数获取自己的标识。

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

示例代码

示例代码位置

multipleThreads/example_01threadCreate.cMakefile 

代码如下:

/*  * created by senllang 2023/12/24  * mail : study@senllang.onaliyun.com  * Copyright (C) 2023-2023, senllang */#include <pthread.h>#include <stdlib.h>#include <stdio.h>#include <string.h>void *thread(void *arg) {  char *ret;  printf("thread() entered with argument '%s'\n", arg);  if ((ret = (char*) malloc(20)) == NULL)   {    perror("malloc() error");    exit(2);  }  strcpy(ret, "This is a test");  pthread_exit(ret);}int main(int argc, char *argv[]) {  pthread_t thid;  void *ret;  if (pthread_create(&thid, NULL, thread, "thread 1") != 0)   {    perror("pthread_create() error");    exit(1);  }  if (pthread_join(thid, &ret) != 0)   {    perror("pthread_create() error");    exit(3);  }  printf("thread exited with '%s'\n", ret);}

编译时,需要在加上线程库 lpthread ,运行结果如下:

[senllang@hatch example_01]$ lltotal 8-rw-r--r--. 1 senllang develops 1265 Dec 24 20:32 Makefile-rw-r--r--. 1 senllang develops  781 Dec 24 20:33 threadCreate.c[senllang@hatch example_01]$ makegcc  -I./ -DTEST_PRO -lpthread -g -c threadCreate.cgcc  -I./ -DTEST_PRO -lpthread -g *.o -o hatch-0-01[senllang@hatch example_01]$ lltotal 40-rwxr-xr-x. 1 senllang develops 21368 Dec 24 20:34 hatch-0-01-rw-r--r--. 1 senllang develops  1265 Dec 24 20:32 Makefile-rw-r--r--. 1 senllang develops   781 Dec 24 20:33 threadCreate.c-rw-r--r--. 1 senllang develops  7600 Dec 24 20:34 threadCreate.o[senllang@hatch example_01]$ ./hatch-0-01 thread() entered with argument 'thread 1'thread exited with 'This is a test'

总结

本文重点分享了线程的创建使用,在main中需要等待线程的结束,因为它是当前进程的主线程,如果它提前结束,由它创建的所有线程也会提前结束,所以它需要等待所有线程结束之后,才能退出。

后面会继续介绍更多线程的知识,完成一个通用线程池的功能。

所有示例的代码已经上传到gitcode上的工程hatchCode,大家有兴趣的可以点star进行关注。

结尾

非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

阅读本书更多章节>>>>

本文链接:https://www.kjpai.cn/xuetang/2024-03-24/147833.html,文章来源:网络cs,作者:淼淼,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

上一篇:C语言内存函数详解

下一篇:返回列表

文章评论