首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux C 编程——多线程

Linux C 编程——多线程

作者头像
felixzhao
发布于 2019-01-31 08:21:48
发布于 2019-01-31 08:21:48
6.9K00
代码可运行
举报
文章被收录于专栏:null的专栏null的专栏
运行总次数:0
代码可运行

线程是计算机中独立运行的最小单位,运行时占用很少的系统资源。与多进程相比,多进程具有多进程不具备的一些优点,其最重要的是:对于多线程来说,其能够比多进程更加节省资源。

1、线程创建

Linux中,新建的线程并不是在原先的进程中,而是系统通过一个系统调用clone()。该系统copy了一个和原先进程完全一样的进程,并在这个进程中执行线程函数。

在Linux中,通过函数pthread_create()函数实现线程的创建:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

其中:

  • thread表示的是一个pthread_t类型的指针;
  • attr用于指定线程的一些属性;
  • start_routine表示的是一个函数指针,该函数是线程调用函数;
  • arg表示的是传递给线程调用函数的参数。

当线程创建成功时,函数pthread_create()返回0,若返回值不为0则表示创建线程失败。对于线程的属性,则在结构体pthread_attr_t中定义。

线程创建的过程如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <malloc.h>

void* thread(void *id){
        pthread_t newthid;

        newthid = pthread_self();
        printf("this is a new thread, thread ID is %u\n", newthid);
        return NULL;
}

int main(){
        int num_thread = 5;
        pthread_t *pt = (pthread_t *)malloc(sizeof(pthread_t) * num_thread);

        printf("main thread, ID is %u\n", pthread_self());
        for (int i = 0; i < num_thread; i++){
                if (pthread_create(&pt[i], NULL, thread, NULL) != 0){
                        printf("thread create failed!\n");
                        return 1;
                }
        }
        sleep(2);
        free(pt);
        return 0;
}

在上述代码中,使用到了pthread_self()函数,该函数的作用是获取本线程的线程ID。在主函数中的sleep()用于将主进程处于等待状态,以让线程执行完成。最终的执行效果如下所示:

那么,如何利用arg向子线程传递参数呢?其具体的实现如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <malloc.h>

void* thread(void *id){
        pthread_t newthid;

        newthid = pthread_self();
        int num = *(int *)id;
        printf("this is a new thread, thread ID is %u,id:%d\n", newthid, num);
        return NULL;
}

int main(){
        //pthread_t thid;
        int num_thread = 5;
        pthread_t *pt = (pthread_t *)malloc(sizeof(pthread_t) * num_thread);
        int * id = (int *)malloc(sizeof(int) * num_thread);

        printf("main thread, ID is %u\n", pthread_self());
        for (int i = 0; i < num_thread; i++){
                id[i] = i;
                if (pthread_create(&pt[i], NULL, thread, &id[i]) != 0){
                        printf("thread create failed!\n");
                        return 1;
                }
        }
        sleep(2);
        free(pt);
        free(id);
        return 0;
}

其最终的执行效果如下图所示:

如果在主进程提前结束,会出现什么情况呢?如下述的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <malloc.h>

void* thread(void *id){
        pthread_t newthid;

        newthid = pthread_self();
        int num = *(int *)id;
        printf("this is a new thread, thread ID is %u,id:%d\n", newthid, num);
        sleep(2);
        printf("thread %u is done!\n", newthid);
        return NULL;
}

int main(){
        //pthread_t thid;
        int num_thread = 5;
        pthread_t *pt = (pthread_t *)malloc(sizeof(pthread_t) * num_thread);
        int * id = (int *)malloc(sizeof(int) * num_thread);

        printf("main thread, ID is %u\n", pthread_self());
        for (int i = 0; i < num_thread; i++){
                id[i] = i;
                if (pthread_create(&pt[i], NULL, thread, &id[i]) != 0){
                        printf("thread create failed!\n");
                        return 1;
                }
        }
        //sleep(2);
        free(pt);
        free(id);
        return 0;
}

此时,主进程提前结束,进程会将资源回收,此时,线程都将退出执行,运行结果如下所示:

2、线程挂起

在上述的实现过程中,为了使得主线程能够等待每一个子线程执行完成后再退出,使用了free()函数,在Linux的多线程中,也可以使用pthread_join()函数用于等待其他线程,函数的具体形式为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int pthread_join(pthread_t thread, void **retval);

函数pthread_join()用来等待一个线程的结束,其调用这将被挂起。

一个线程仅允许一个线程使用pthread_join()等待它的终止。

如需要在主线程中等待每一个子线程的结束,如下述代码所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <malloc.h>

void* thread(void *id){
        pthread_t newthid;

        newthid = pthread_self();
        int num = *(int *)id;
        printf("this is a new thread, thread ID is %u,id:%d\n", newthid, num);
        free(3);
        printf("thread %u is done\n", newthid);
        return NULL;
}

int main(){
        int num_thread = 5;
        pthread_t *pt = (pthread_t *)malloc(sizeof(pthread_t) * num_thread);
        int * id = (int *)malloc(sizeof(int) * num_thread);

        printf("main thread, ID is %u\n", pthread_self());
        for (int i = 0; i < num_thread; i++){
                id[i] = i;
                if (pthread_create(&pt[i], NULL, thread, &id[i]) != 0){
                        printf("thread create failed!\n");
                        return 1;
                }
        }
        for (int i = 0; i < num_thread; i++){
                pthread_join(pt[i], NULL);
        }
        free(pt);
        free(id);
        return 0;
}

最终的执行效果如下所示:

注:在编译的时候需要链接libpthread.a: g++ xx.cc -lpthread -o xx

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017年03月13日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
初谈Linux多线程--线程控制
在Linux中,线程执行的是进程代码的一部分,也就是说,线程是进程的实体,可以看作是进程内的一个执行单元,我们将这些不同的执行单元称之为轻量级进程,不同线程之间可以通过共享内存来进行通信。
南桥
2024/08/02
3050
初谈Linux多线程--线程控制
Linux之多线程编程实例
pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。顺便说一下,Linux
用户6754675
2020/04/02
1.8K0
多线程编程C语言版
什么是多线程,提出这个问题的时候,我还是很老实的拿出操作系统的书,按着上面的话敲下“为了减少进程切换和创建开销,提高执行效率和节省资源,我们引入了线程的概念,与进程相比较,线程是CPU调度的一个基本单位。”
DeROy
2021/11/16
3.8K0
多线程编程C语言版
linux网络编程之posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序
本文介绍了多线程和线程同步的基础知识,并基于Linux环境进行了详细的实例分析。通过本文的学习,读者可以掌握多线程和线程同步的基本原理,并能够使用相关技术解决实际问题。
s1mba
2017/12/28
3.5K0
linux网络编程之posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序
线程(一)线程概念+线程控制
pthread_t 到底是什么类型呢?取决于实现。对于Linux目前实现的NPTL实现而言,pthread_t类型的线程ID,本质就是一个进程地址空间上的一个地址。
海盗船长
2020/08/27
1.2K0
一文搞懂Linux多线程【下】
在观看本博客之前,建议大家先看一文搞懂Linux多线程【上】由于上一篇博客篇幅太长,为了更好的阅读体验,我拆成了两篇博客。那么接下来,在上一篇的基础上,我们继续学习Linux信号部分。今天,我们主要学习Linux多线程控制问题。
破晓的历程
2024/08/20
2340
一文搞懂Linux多线程【下】
Linux C 编程——互斥锁mutex
1、多线程的问题引入 多线程的最大的特点是资源的共享,但是,当多个线程同时去操作(同时去改变)一个临界资源时,会破坏临界资源。如利用多线程同时写一个文件: #include <stdio.h> #include <pthread.h> #include <malloc.h> const char filename[] = "hello"; void* thread(void *id){ int num = *(int *)id; // 写文件的操作 F
felixzhao
2018/03/16
5.7K0
Linux C 编程——互斥锁mutex
c++ 网络编程(九)TCP/IP LINUX/windows--使用IOCP模型 多线程超详细教程 以及 多线程实现服务端
原文链接:https://www.cnblogs.com/DOMLX/p/9661012.html
徐飞机
2018/09/30
3.4K0
c++ 网络编程(九)TCP/IP LINUX/windows--使用IOCP模型      多线程超详细教程 以及 多线程实现服务端
Linux多线程编程实例解析
Linux系统下的多线程遵循POSIX线程接口,称为 pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。顺便说一下,Linux 下pthread的实现是通过系统调用clone()来实现的。clone()是 Linux所特有的系统调用,它的使用方式类似fork,关于clone()的详细情况,有兴趣的读者可以去查看有关文档说明。下面我们展示一个最简单的 多线程程序 pthread_create.c。 一个重要的线程创建函数原型:
用户6754675
2019/11/27
2.2K0
Linux系统编程-几个多线程DEMO
本章将分为两大部分进行讲解,前半部分将引出线程的使用场景及基本概念,通过示例代码来说明一个线程创建到退出到回收的基本流程。后半部分则会通过示例代码来说明如果控制好线程,从临界资源访问与线程的执行顺序控制上引出互斥锁、信号量的概念与使用方法。
韦东山
2020/09/30
1.9K0
Linux系统编程-几个多线程DEMO
linux网络编程学习笔记之五 —–并发机制与线程�
简述下常见的进程和线程分配方式:(好吧,我仅仅是举几个样例作为笔记。。。并发的水太深了,不敢妄谈。。。)
全栈程序员站长
2022/07/12
3670
linux网络编程学习笔记之五 —–并发机制与线程�
Linux线程-概念和控制
注:pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了
用户9645905
2022/11/30
1.3K0
Linux线程-概念和控制
Linux应用开发【第五章】线程编程应用开发
​ 本章将分为两大部分进行讲解,前半部分将引出线程的使用场景及基本概念,通过示例代码来说明一个线程创建到退出到回收的基本流程。后半部分则会通过示例代码来说明如果控制好线程,从临界资源访问与线程的执行顺序控制上引出互斥锁、信号量的概念与使用方法。
韦东山
2021/12/15
1.6K0
Linux应用开发【第五章】线程编程应用开发
Linux多线程Pthread学习小结
POSIX thread 简称为pthread,Posix线程是一个POSIX标准线程.该标准定义内部API创建和操纵线程.
阳光岛主
2019/02/20
2.2K0
Posix线程 它们那一大家子事儿,要觉得好你就收藏进被窝里慢慢看 (1)
官方话就是:是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
看、未来
2020/08/25
4160
Posix线程 它们那一大家子事儿,要觉得好你就收藏进被窝里慢慢看  (1)
【Linux】盘点<多线程控制>基本操作&演示:创建&中止&等待&分离
YY的秘密代码小屋
2024/10/17
2960
【Linux】盘点<多线程控制>基本操作&演示:创建&中止&等待&分离
【Linux】:线程概念与控制
CPU看到的: 执行流 <= 进程 注意:Linux中的执行流叫:轻量级进程
IsLand1314
2024/12/20
3300
【Linux】:线程概念与控制
【Linux】一篇文章带你了解Linux多线程&&线程控制&&线程安全&&线程互斥详解
进程的多个线程共享 同一地址空间,因此Text Segment、Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境:
用户10925563
2024/08/29
3870
【Linux】一篇文章带你了解Linux多线程&&线程控制&&线程安全&&线程互斥详解
【Linux】从零开始认识多线程 --- 线程控制
复习的差不多了,我们了解了线程的基本概念,接下来就要开始学习如何管理线程 — 线程控制。根据我们之前学习的进程控制,大概可以估计一下线程控制的基本接口:线程创建 , 线程等待 , 线程退出…
叫我龙翔
2024/07/16
2120
【Linux】从零开始认识多线程 --- 线程控制
【Linux】多线程——线程概念|Linux下进程与线程|线程控制
地址空间是进程能看到的资源窗口:一个进程能看到代码区、共享区、内核区、堆栈区,大部分的资源都是在地址空间上看到的
平凡的人1
2023/10/15
1.1K0
【Linux】多线程——线程概念|Linux下进程与线程|线程控制
推荐阅读
相关推荐
初谈Linux多线程--线程控制
更多 >
交个朋友
加入[跨境业务] 腾讯云官方方案交流站
共享跨境方案指南 洞察行业动向
加入架构与运维学习入门群
系统架构设计入门 运维体系构建指南
加入HAI高性能应用服务器交流群
探索HAI应用新境界 共享实践心得
换一批
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档