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

【Linux】多线程

进程和线程

进程:一个正在运行的程序。

状态:就绪,运行,阻塞;

线程是进程中的一个执行路径,一个进程中至少有一个主线程(main函数);

有多条执行路径为多线程。

创建一个线程

用pthread_create()创建

记得编译的时候后面加-pthread

多个线程用同一个进程的地址空间

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
void *fun(void *arg)//这是一个线程
{for(int i=0;i<5;i++){printf(“fun run\n”);sleep(1);
}
pthread_exit(“fun over”);//可以返回线程信息给主线程
}
int main()
{pthread_t id;
//create执行一次创建一个进程pthread_create(&id,NULL,fun,NULL);//创建了一个fun线程for(int i=0;i<5;i++){printf(“main run\n”);sleep(1);
}
char *s = NULL;pthread_join(id,(void**)&s);
//等待线程返回的信息,如果子线程没有运行完,主线程会被阻塞,可以防止fun线程没有运行完main就结束。
printf(“s=%s\n”,s);//不能用临时变量
exit(0);
}

两个路径同时进行,主函数(主进程)退出,其余进程也会结束,尽量让主函数慢点退出,sleep一下。

当然,用了pthread_join();接收返回信息阻塞可以不用sleep

了解程序的并发运行

并行是特殊的并发,我的虚拟机有4个处理器,所以准确来说这几个线程应该是并行的。

同时创建多个线程并打印自己是第几个线程:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
void *fun(void *arg)//这是一个线程
{int index = *(int*)arg;printf(“index=%d\n”,index);
sleep(1);printf(“index=%d\n”,index);
pthread_exit(NULL);//可以返回线程信息给主线程
}
int main()
{pthread_t id[5];
//create执行一次创建一个进程
int i=0;for(i=0;i<5;i++)
{pthread_create(&id[i],NULL,fun,(void*)&i);//创建线程,传地址
}
for(i=0;i<5;i++)
{pthread_join(id[i],NULL);
}exit(0);
}

运行结果:

程序运行有不确定性(少用多线程)

因为线程获取i是靠i的地址,可能第一次循环的时候这些线程还没来得及获取i的值,到第二个for循环i被置0时才取得i的值,所以线程输出全是0。

获取i的值的速度差不多(同时获取值出现几个相同的),写入缓冲区的速度不一样不一定从0到4。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
int g_count = 1;
void *fun(void *arg)//这是一个线程
{for(int i=0;i<1000;i++){printf(“g_count=%d\n”,g_count++);}
pthread_exit(NULL);//可以返回线程信息给主线程
}
int main()
{pthread_t id[5];
//create执行一次创建一个进程for(int i=0;i<5;i++)
{pthread_create(&id[i],NULL,fun,NULL);//创建线程,传地址
}
for(int i=0;i<5;i++)
{pthread_join(id[i],NULL);
}exit(0);
}

理想的结果应该是5000,每个线程加1000次,但是结果会出现4999,4998等,这是因为两个进程同时执行了++,然后把数值存回去,本来应加两次变成了加一次,导致结果变小了。

http://www.lryc.cn/news/42215.html

相关文章:

  • Qt 设置窗口背景图片的几种方法实例
  • springcloud微服务架构搭建过程
  • LeetCode:215. 数组中的第K个最大元素
  • vue面试题(day06)
  • 22 k8s常用命令
  • 基于ESP32做低功耗墨水屏时钟
  • 常见路由器开源系统(固件)简介
  • HCIE-Cloud Computing LAB备考第二步:逐题攻破--第二题:FusionAccess-搭建FA实验环境之安装基础组件和初始化ITA组件
  • Android APP检查设备是否为平板
  • MP:使用步骤、分页、queryWrapper
  • C++ string类
  • 虚拟机断电centos无法启动
  • python学习之基于Python的人脸识别技术学习
  • [Qt][Android] Qt for Android 环境搭建
  • maven setting 配置
  • 【0基础学爬虫】爬虫基础之网络请求库的使用
  • 超级实用,解密云原生监控技术,使用prometheus轻松搞定redis监控
  • 音视频开发—MediaCodec 解码H264/H265码流视频
  • CVPR 2023|淘宝视频质量评价算法被顶会收录
  • 【C++学习】继承
  • 【03173】2020年8月高等教育自学考试-软件开发工具
  • Java中的String类
  • 【java】笔试强训Day3【在字符串中找出连续最长的数字串与数组中出现次数超过一半的数字】
  • 一文7个步骤从0到1教你搭建Selenium 自动化测试环境
  • Oracle目录应急清理
  • 使用 OBS 进行区域录制
  • aws eks 配置授权额外的用户和角色访问集群
  • MagicalCoder可视化开发平台:轻松搭建业务系统,为企业创造更多价值
  • 8个不能错过的程序员必备网站,惊艳到我了!!!
  • Mybatis(二):实现“增删改查”