Webserver(3.1)线程

目录

  • 创建线程
  • 终止线程
  • 连接已终止的进程
    • 二级指针
  • 线程分离
  • 线程取消
  • 线程属性
  • 线程同步
    • 多线程卖票

创建线程

编译时需要加-pthread

gcc pthread_create.c -o create -pthread

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

void * callback(void * arg) {
    printf("child thread...\n");
    return NULL;
}

int main(){

    pthread_t tid;
    //创建一个子线程
    int ret=pthread_create(&tid,NULL,callback,NULL);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }

    for(int i=0;i<5;i++){
        printf("%d\n",i);
    }

    sleep(2);

    return 0;
}

在这里插入图片描述

终止线程

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

void * callback(void * arg){
    printf("child thread id:%ld\n",pthread_self());
    return NULL;
}
int main(){

    //创建一个子线程
    pthread_t tid;
    int ret=pthread_create(&tid,NULL,callback,NULL);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }
    //主线程
    for(int i=0;i<200;i++){
        printf("%d\n",i);
    }
    printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());

    //让线程退出,当主线程退出时,不会影响其他正常运行的线程
    pthread_exit(NULL);

    return 0;
}

在这里插入图片描述
主线程和子线程交替运行
在这里插入图片描述

连接已终止的进程

pthread_join是一个阻塞的行为,子线程没结束时不会回收的,不会执行。

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

void * callback(void * arg){
    sleep(3);
    printf("child thread id:%ld\n",pthread_self());
    return NULL;
}
int main(){

    //创建一个子线程
    pthread_t tid;
    int ret=pthread_create(&tid,NULL,callback,NULL);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }
    //主线程
    for(int i=0;i<200;i++){
        printf("%d\n",i);
    }
    printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
    //主线程调用pthread_join()回收子线程的资源
    ret=pthread_join(tid,NULL);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }
    printf("回收子线程资源成功\n");

    //让线程退出,当主线程退出时,不会影响其他正常运行的线程
    pthread_exit(NULL);

    return 0;
}

在这里插入图片描述

二级指针

#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
int value=10;

void * callback(void * arg){
    // sleep(3);
    printf("child thread id:%ld\n",pthread_self());
    // int value=10;
    pthread_exit((void *)&value);
    // return NULL;
}
int main(){

    //创建一个子线程
    pthread_t tid;
    int ret=pthread_create(&tid,NULL,callback,NULL);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }
    //主线程
    for(int i=0;i<200;i++){
        printf("%d\n",i);
    }
    printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
    //主线程调用pthread_join()回收子线程的资源
    int * thread_retval;
    ret=pthread_join(tid,(void **)&thread_retval);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }
    printf("exit data:%d\n",*thread_retval);
    printf("回收子线程资源成功\n");

    //让线程退出,当主线程退出时,不会影响其他正常运行的线程
    pthread_exit(NULL);

    return 0;
}

在这里插入图片描述

线程分离

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

void * callback(void * arg){
    printf("child thread id:%ld\n",pthread_self());
    return NULL;
}

int main(){

    //创建一个子进程
    pthread_t tid;

    int ret=pthread_create(&tid,NULL,callback,NULL);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }
    //输出主线程和子线程的id
    printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
    //设置子线程分离,子线程分离后,子线程结束时对应的资源就不需要主线程释放
    pthread_detach(tid);


    pthread_exit(NULL);

    return 0;
}

在这里插入图片描述

分离之后,就不能进行连接了

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

void * callback(void * arg){
    printf("child thread id:%ld\n",pthread_self());
    return NULL;
}

int main(){

    //创建一个子进程
    pthread_t tid;

    int ret=pthread_create(&tid,NULL,callback,NULL);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }
    //输出主线程和子线程的id
    printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
    //设置子线程分离,子线程分离后,子线程结束时对应的资源就不需要主线程释放
    ret=pthread_detach(tid);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }
    //设置分离后,对分离的子线程进行连接
    ret=pthread_join(tid,NULL);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }

    pthread_exit(NULL);

    return 0;
}

在这里插入图片描述

线程取消

线程取消不是立马终止,而是遇到取消点的时候终止

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

void * callback(void * arg){
    printf("child thread id:%ld\n",pthread_self());
     for(int i=0;i<50;i++){
        printf("child:%d\n",i);
    }
    return NULL;
}

int main(){

    //创建一个子进程
    pthread_t tid;

    int ret=pthread_create(&tid,NULL,callback,NULL);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }
    
    //取消线程
    pthread_cancel(tid);
    
    for(int i=0;i<50;i++){
        printf("%d\n",i);
    }

    //输出主线程和子线程的id
    printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
    
    pthread_exit(NULL);

    return 0;
}

30就结束了,因为到达了取消点
在这里插入图片描述

线程属性

设置线程分离

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

void * callback(void * arg){
    printf("child thread id:%ld\n",pthread_self());
    return NULL;
}

int main(){

    //创建一个线程属性变量
    pthread_attr_t attr;
    //初始化属性变量
    pthread_attr_init(&attr);

    //设置属性
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

    //创建一个子进程
    pthread_t tid;

    int ret=pthread_create(&tid,&attr,callback,NULL);
    if(ret!=0){
        char * errstr=strerror(ret);
        printf("error:%s\n",errstr);
    }
    //输出主线程和子线程的id
    printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
    
    //释放线程属性资源
    pthread_attr_destroy(&attr);
    
    pthread_exit(NULL);

    return 0;
}

线程同步

多线程卖票

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
int tickets=100;//局部变量就是每个人卖100张,全局变量就是一起卖100张,所有线程共享一份资源

void * sellticket(void * arg){
    //卖票
    while(tickets>0){
        usleep(3000);
        printf("%ld 正在卖第 %d 张门票\n",pthread_self(),tickets);
        tickets--;
    }
    return NULL;
}
int main(){

    //创建3个子线程
    pthread_t tid1,tid2,tid3;
    pthread_create(&tid1,NULL,sellticket,NULL);
    pthread_create(&tid2,NULL,sellticket,NULL);
    pthread_create(&tid3,NULL,sellticket,NULL);

    //回收子线程的资源,阻塞
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    pthread_join(tid3,NULL);

    //设置线程分离
    // pthread_detach(tid1);
    // pthread_detach(tid2);
    // pthread_detach(tid3);
    pthread_exit(NULL);//退出主线程





    return 0;
}

会产生卖同一张门票的情况
对共享数据的操作同一个时间只能一个线程
必须确保多个线程不会同时修改同一变量,或者某一线程不会读取正在由其他线程修改的变量。
这段代码的执行应该为原子操作,不能被其他线程中断
线程同步会降低效率,但是安全
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/908802.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WPS实现手机电脑同步文件

复制链接&#xff0c;发送微信&#xff0c;即可在手机端打开同步编辑文档。 当手机编辑文档后&#xff0c;会有如下提示: 根据提示&#xff0c;可选择文件更新版本。

ES海量数据插入如何优化性能?

2024年10月NJSD技术盛典暨第十届NJSD软件开发者大会、第八届IAS互联网架构大会在南京召开。百度文心快码总经理臧志分享了《AI原生研发新范式的实践与思考》&#xff0c;探讨了大模型赋能下的研发变革及如何在公司和行业中落地&#xff0c;AI原生研发新范式的内涵和推动经验。 …

【linux】HTTPS 协议原理

1. 了解 HTTPS 协议原理 &#xff08;一&#xff09;认识 HTTPS HTTPS 也是一种应用层协议&#xff0c;是在 HTTP 协议的基础上引入了一个加密层 因为 HTTP协议的内容都是按照文本的方式进行传输的&#xff0c;这个过程中&#xff0c;可能会出现一些篡改的情况 &#xff08;…

labview学习总结

labview学习总结 安装labview的特点一、图形化编程范式二、并行执行机制三、硬件集成能力四、应用领域优势五、开发效率六、系统集成能力**labview基本组成示意图****常用程序结构图解**结语 基础知识介绍界面前后面板的概念平铺式和层叠式 帧的概念结构类型顺序结构for循环whi…

PostgreSQL技术内幕17:PG分区表

文章目录 0.简介1.概念介绍2.分区表技术产生的背景3.分区类型及使用方式4.实现原理4.1 分区表创建4.2 分区表查询4.3 分区表写入4.4 分区表删除 0.简介 本文主要介绍PG中分区表的概念&#xff0c;产生分区表技术的原因&#xff0c;使用方式和其内部实现原理&#xff0c;旨在能…

RHCSA课后练习3(网络与磁盘)

1、配置网络&#xff1a;为网卡添加一个本网段IPV4地址&#xff0c;x.x.x.123 涉及的知识点 配置网络&#xff1a; ens160&#xff1a;en---表示以太网 wl---表示无线局域网 ww---表示无线广域网 注意&#xff1a;一个网络接口&#xff0c;可以有多个网络连接&#xff0c;但…

开发人员需要知道的 20个Git命令行技巧

前言 大多数开发人员每天都会使用 Git&#xff0c;但许多人只是对其功能略知一二。 学习一些 git 命令行技巧可以改变游戏规则&#xff0c;让你更高效、更有成效&#xff0c;对版本控制更有信心。 那么&#xff0c;让我们深入了解每个开发人员工具包中都应该有的 20 个 Git …

第十一章 综合案例--“精品课程网站“开发

1.网站的开发流程 网站开发流程通常分为几个关键阶段&#xff0c;每个阶段都有其特定的任务和目标。以下是一个典型的网站开发流程&#xff1a; 1. 需求分析 目标设定&#xff1a;明确网站的目标和目的。 受众研究&#xff1a;确定目标用户&#xff0c;了解他们的需求和偏好。…

VSCode 1.82之后的vscode server离线安装

概述 因为今天在公司开发项目的时候&#xff0c;需要离线配置vscode远程开发环境&#xff0c; 根据参考链接1配置了一遍&#xff0c;不管怎么重启&#xff0c;VSCODE都还是提示下载vscode server&#xff0c;后面在官方issue上找到了解决方案 解决方案 修改Remote SSH的配置…

Linux和,FreeRTOS 任务调度原理,r0-r15寄存器,以及移植freertos(一)

目录、 1、r0-r15寄存器&#xff0c;保护现场&#xff0c;任务切换的原理 2、freertos移植 3、freertos的任务管理。 一、前言 写这篇文章的目的&#xff0c;是之前面试官&#xff0c;刚好问到我&#xff0c;移植FreeRTOS 到mcu&#xff0c;需要做哪些步骤&#xff0c;当时回…

「Mac畅玩鸿蒙与硬件28」UI互动应用篇5 - 滑动选择器实现

本篇将带你实现一个滑动选择器应用&#xff0c;用户可以通过滑动条选择不同的数值&#xff0c;并实时查看选定的值和提示。这是一个学习如何使用 Slider 组件、状态管理和动态文本更新的良好实践。 关键词 UI互动应用Slider 组件状态管理动态数值更新用户交互 一、功能说明 在…

云服务器防火墙设置方法

云服务器防火墙设置方法通常包括&#xff1a;第一步&#xff1a;登录控制台&#xff0c;第二步&#xff1a;配置安全组规则&#xff0c;第三步&#xff1a;添加和编辑规则&#xff0c;第四步&#xff1a;启用或停用规则&#xff0c;第五步&#xff1a;保存并应用配置。云服务器…

数据中台一键大解析!

自从互联玩企业掀起了数据中台风&#xff0c;数据中台这个点马上就火起来了&#xff0c;短短几年数据中台就得到了极高的热度&#xff0c;一大堆企业也在跟风做数据中台&#xff0c;都把数据中台作为企业数字化转型的救命稻草&#xff0c;可是如果我告诉你数据中台并不是万能钥…

【第一个qt项目的实现和介绍以及程序分析】【正点原子】嵌入式Qt5 C++开发视频

qt项目的实现和介绍 1.第一个qt项目  &#xff08;1).创建qt工程    [1].创建一个存放qt的目录    [2].新建一个qt工程    [3].编译第一个工程    发生错误时的解决方式 二.QT文件介绍  (1).工程中文件简单介绍  (2).项目文件代码流程介绍    [1].添…

计算机网络:网络层 —— 网络地址转换 NAT

文章目录 网络地址转换 NAT 概述最基本的 NAT 方法NAT 转换表的作用 网络地址与端口号转换 NAPTNAT 和 NAPT 的缺陷 网络地址转换 NAT 概述 尽管因特网采用了无分类编址方法来减缓 IPv4 地址空间耗尽的速度&#xff0c;但由于因特网用户数量的急剧增长&#xff0c;特别是大量小…

【算法】【优选算法】双指针(下)

目录 一、611.有效三⻆形的个数1.1 左右指针解法1.2 暴力解法 二、LCR 179.查找总价格为目标值的两个商品2.1 左右指针解法2.2 暴力解法 三、15.三数之和3.1 左右指针解法3.2 暴力解法 四、18.四数之和4.1 左右指针解法4.2 暴力解法 一、611.有效三⻆形的个数 题目链接&#x…

面试题分享11月1日

1、过滤器和拦截器的区别 过滤器是基于spring的 拦截器是基于Java Web的 2、session 和 cookie 的区别、关系 cookie session 存储位置 保存在浏览器 &#xff08;客户端&#xff09; 保存在服务器 存储数据大小 限制大小&#xff0c;存储数据约为4KB 不限制大小&…

VR 创业之路:从《I Expect You To Die》到未来展望

今年是 Reality Labs 成立 10 周年&#xff0c;Meta 每周都会与不同的 XR 先驱进行交流&#xff0c;探讨他们在行业中的经历、经验教训以及对未来的展望。本次&#xff0c;他们与游戏设计师、作家兼 Schell Games CEO Jesse Schell 进行了深入交谈&#xff0c;了解了他的个人故…

【大数据学习 | kafka】简述kafka的消费者consumer

1. 消费者的结构 能够在kafka中拉取数据进行消费的组件或者程序都叫做消费者。 这里面要涉及到一个动作叫做拉取。 首先我们要知道kafka这个消息队列主要的功能就是起到缓冲的作用&#xff0c;比如flume采集数据然后交给spark或者flink进行计算分析&#xff0c;但是flume采用的…

​Controlnet作者新作IC-light V2:基于FLUX训练,支持处理风格化图像,细节远高于SD1.5。

大家好&#xff01;今天我要向大家介绍一个超级有趣的话题——Controlnet作者的新作IC-light V2&#xff01;这个工具基于FLUX训练&#xff0c;能够支持处理风格化图像&#xff0c;并且细节表现远高于SD1.5。 想象一下&#xff0c;你有一个强大的AI助手&#xff0c;它能够根据…