IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 基于VS2019 C++的跨平台(Linux)开发(2.5)——线程同步 -> 正文阅读

[Java知识库]基于VS2019 C++的跨平台(Linux)开发(2.5)——线程同步

一、前言

首先来回顾一下cpu的随机轮转机制

  • 顺序随机(固定优先级情况下)
  • 时间随机(可能有固定时间,就像鸿蒙OS芯片是10毫秒)
  • 次数随机

其次是进程与线程的区别

  • 1、进程是资源分配的基本单位,线程是CPU调度的基本单位
  • 2、一个进程中可以包含n条线程,n条线程同时共享当前进程的所有资源
  • 3、进程无法共享数据(要通过IPC),在一个进程内多条线程可以共享数据

计算机会为一个进程开辟磁盘、内存和cpu等,用进程来计算,进程再开出线程,线程的开辟更加的节省资源开销,线程再共享当前进程的所有资源

区别可以按数据共享、开辟空间、创建上开销、应用场景上分点列举

二、线程同步概述

1、线程同步

概念:两个或多个线程同时进行时,经常需要访问到公共资源或代码的关键部分。

2、线程同步问题

概念:多个线程争抢CPU的执行权,同时访问同一片公共区域时产生的线程同步的数据不安全问题(例如:一个线程可能没有执行完,执行了一半就去执行另外一个线程)

原因:cpu随机轮片,执行时间随机

解决方法:使用线程互斥量或者信号量

3、用互斥量进行同步

  • 程序员给某个对象加上一把“锁”,每次只允许一个线程去访问它
  • 如果想对代码关键部分的访问进行控制,你必须在进入这段代码之前锁定一把互斥量,在完成操作后再打开它

4、互斥量的使用

使用步骤如下

(1)互斥量的声明(全局变量)

pthread_mutex_t mutex;//全局的锁

(2)互斥量的初始化

pthread_mutex_init(&mutex, NULL);

(3)互斥量的加锁与解锁

        pthread_mutex_lock(&mutex);
		cout << "子线程2号 student.name = " << data.name << endl;
		cout << "子线程2号 student.sex = " << data.sex << endl;
		pthread_mutex_unlock(&mutex);
		sleep(1);

加锁与解锁的中间的部分是公共资源(全局变量、共享内存、单例设计等),也就是多个线程都要访问的部分。

示例

1、代码

#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
//线程执行函数 类似run
using namespace std;

// 一个进程中全局变量在多个线程中可以共享 number++ 可以进行叠加

int  number = 0;
//互斥量 用来实现线程锁
pthread_mutex_t mutex;
typedef struct student
{
	char name[10];
	char sex[10];
}STU;
STU data = { "",""};

void* pthread_func(void *p)
{
	//char *p1= (char*)p;
	while (true)//两个while同时跑
	{
		/*number++;
		cout << "子线程1号执行。。。。。。number = "<< number ++<< "  p1 = " << p1 << endl;*/

		pthread_mutex_lock(&mutex);
		if (number % 2 == 0)
		{
			strcpy(data.name,"张三");
			strcpy(data.sex, "男");
		}
		else
		{
			strcpy(data.name, "李四");
			strcpy(data.sex, "女");
		}
		pthread_mutex_unlock(&mutex);
		sleep(1);
	}
}
void* pthread_func2(void* p)
{

	while (true)//两个while同时跑
	{
		/*int* p2 = (int*)p;
		number++;
		cout << "子线程2号执行。。。。。。number = " << number++ << "   p2 = " <<*p2 << endl;*/

		

		pthread_mutex_lock(&mutex);
		cout << "子线程2号 student.name = " << data.name << endl;
		cout << "子线程2号 student.sex = " << data.sex << endl;
		pthread_mutex_unlock(&mutex);
		sleep(1);
	}
}
int main()
{

	
	pthread_t thread_id;
	pthread_t thread_id2;
	char buf[15] = { "hello" };
	int temp = 666;
	pthread_mutex_init(&mutex, NULL);
	if (pthread_create(&thread_id,NULL, pthread_func, NULL))
	{
		perror("pthread_create error");
	}
	if ( pthread_create(&thread_id2, NULL, pthread_func2, NULL))
	{
		perror("pthread_create error");
	}

	while (true)
	{
		
		cout << "主线程执行  number = " << number++ << endl;  
		

		sleep(1);
	}
	return 0;


}

2、运行结果

?

结果分析:

1、第一次打印的name和sex是空的,因为cpu调度线程的顺序随机,即使是线程1先开,线程2后开,但对于cpu来说他们两是公平竞争执行权的(不代表先写就先执行)。图中可以看出运行的时候先跑了主线程,之后立刻跑了线程2(打印),线程1还没执行(修改),所以导致打印的数据是空的

2、因为使用了互斥量,所以结果正常。如果不加锁解锁,因为cpu执行时间也随机,在拷贝完李四这个名字后(还没有做性别拷贝)就立刻被切换到线程2中执行,就打印了一个名字后又立刻被切换到线程1中拷贝性别,拷贝完又立刻? 被切换到线程2中打印性别,导致最后把李四改成男的

时间随机也就是进入为while循环里的代码还没有全部走完,就被切换成其他线程执行

总结:

1、为什么通过上锁就能解决同步问题?
本质原因是pthread_mutex_lock(&mutex)是一个阻塞式函数,只有遇到unlock后才会执行lock操作
例如:线程1执行到一半,此时线程2想切换成自己执行,因为上了锁,只有等到线程1执行了unlock 才能执行

2、为什么不能在锁中sleep (1) ?
sleep 的机制是类似于切换线程了,这时候没有解锁,线程就进入死锁状态。

3、注意

  • 不能有无法结束的死循环
  • 操作部分应该是公共资源或者关键代码
  • 操作完,必须解锁
    ?

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 23:11:18  更:2022-04-01 23:12:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:15:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码