1)lock_guard有两个构造函数,使用方法如下(注意:一定要声明一个局部的lock_guard对象):
std::mutex mtx;
(1)一个参数的使用方法:lock_guard lock(mtx); //直接自动上锁,相当于调用mtx.lock()函数;
(2)两个参数的使用方法:lock_guard lock1(mutex,adopt_lock); //需要手动(自己)上锁;所以在执行这条语句之前,需要手动上锁,代码如:mtx.lock();
(3) lock_guard模板类的使用,代码如下:

#include <iostream>
#include <mutex>
#include <vector>
#include <stdio.h>
#include <thread>using namespace std;std::string ReadMsg(void)
{char buf[30] = {0};static int i = 100;sprintf(buf,"%d",i--);return buf;
}class CMutexTest
{public: void recv_msg();void read_msg();
private:vector<string> msgQueue;mutex mtx; 实例化mtx对象,不要理解为定义变量
};void CMutexTest::recv_msg(void)
{while(1){string tmpSsg = ReadMsg();cout<< "模拟接收数据后存入 vector数组中: " << tmpSsg <<endl;//使用{}限定lock_guard作用域{std::lock_guard<mutex> mylock(mtx); //用此语句替换了mtx.lock();自动锁定msgQueue.push_back(tmpSsg);}this_thread::sleep_for(chrono::milliseconds(5));}
}void CMutexTest::read_msg(void)
{while(1){//std::lock_gurad也可以传入两个参数,第一个参数为adopt_lock标识时,表示构造函数中不再进行互斥量锁定,因此此时需要提前手动锁定。mtx.lock(); //提前手动锁定std::lock_guard<mutex> mylock(mtx,adopt_lock); //这里必须用adopt_lock这个参数if(!msgQueue.empty()){//处理消息并移除string msg = msgQueue.front();cout<<"从动态数组中读取数据: "<<msg<<endl;msgQueue.erase(msgQueue.begin());}this_thread::sleep_for(chrono::milliseconds(10));}
}int main(void)
{CMutexTest message;thread th1(&CMutexTest::recv_msg,&message);thread th2(&CMutexTest::read_msg,&message);th1.join();th2.join();return 0;
}

运行结果如下:

模拟接收数据后存入 vector数组中: 100
从动态数组中读取数据: 100
模拟接收数据后存入 vector数组中: 99
从动态数组中读取数据: 99
模拟接收数据后存入 vector数组中: 98
从动态数组中读取数据: 98
模拟接收数据后存入 vector数组中: 97
从动态数组中读取数据: 97
模拟接收数据后存入 vector数组中: 96
从动态数组中读取数据: 96
模拟接收数据后存入 vector数组中: 95
从动态数组中读取数据: 95
模拟接收数据后存入 vector数组中: 94

对上面lock_guard的总结:
定义两个线程,一个是模拟从设备上(设备为自定义int型数据)读取数据后,存储到vector动态数组中;
一个线程从动态数组中读取数据后,并清除vector数组内容;
lock_guard具有两种构造方法:
lock_guard(mutex& m)
lock_guard(mutex& m, adopt_lock)
其中mutex& m是互斥量,参数adopt_lock表示假定调用线程已经获得互斥体所有权并对其进行管理了。
从lock_guard<>可以看出它是一个模板类,它在自身作用域(生命周期)中具有构造时加锁,析构时解锁的功能。

2)fread和fwrite函数应用案例(读、写二进制文件),代码如下:

#include<stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <poll.h>
#include <errno.h>
#include <fcntl.h>struct pirate
{char name[100];unsigned long booty;u_int16_t beard_len;
};/*
size_t   fread(   void   *buffer,   size_t   size,   size_t   count,   FILE   *stream   ) buffer   是读取的数据存放的内存的指针(可以是数组,也可以是新开辟的空间,buffer就是一个索引)   size     是每次读取的字节数  count    是读取次数  strean   是要读取的文件的指针  例如: 从文件fp里读取100个字节   可用以下语句  fread(buffer,100,1,fp)  fread(buffer,50,2,fp)  fread(buffer,1,100,fp)
*///二进制文件读、写的案例 用fread 和 fwrite 库函数
//fwrite和fread用 fopen 文件指针进行数据读写;
//write和read用 open 文件描述符进行数据读写;
//文件指针和文件描述符是完全不同的两个概念;
int main(void)
{FILE *in, *out;struct pirate blackbeard = {"jiang",950,48};struct pirate readMsg;out = fopen("data","w");if(out == NULL){perror("fopen");    return 1;}if(!fwrite(&blackbeard,sizeof(struct pirate),1,out)){perror("fwrite");    return 1;}if(fclose(out)){perror("fclose");    return 1;        }in = fopen("data","r");if(in == NULL){perror("fopen");    return 1;}if(!fread(&readMsg,sizeof(struct pirate),1,in)){perror("fread");    return 1;}if(fclose(in)){perror("fclose");    return 1;        }printf("name: %s booty: %lu beard_len %u\r\n",  \readMsg.name,readMsg.booty,readMsg.beard_len);
}

输出结果如下:

name: jiang booty: 950 beard_len: 48

3)进程间通信中的信号量案例(防止死锁发生),哲学家吃饭问题的代码案例如下:

#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/wait.h>
//不可能出现两个相邻的两个哲学家出现同时吃的状态!#define ERR_EXIT(m) \do { \perror(m); \exit(EXIT_FAILURE); \} while(0)union semun
{int val;    /* Value for SETVAL */struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */unsigned short  *array;  /* Array for GETALL, SETALL */struct seminfo  *__buf;  /* Buffer for IPC_INFO (Linux-specific) */
};int semid;#define DELAY (rand() % 5 + 1)int wait_1fork(int no)//
{struct sembuf sb = {(unsigned short)no, -1, 0};//对信号量集中第no个信号进行操作,对信号量的计数值减1,int ret = semop(semid, &sb, 1);//用来进行P操作(信号量集标识,数组,数组中包含元素个数)if (ret == -1)ERR_EXIT("semop");return ret;
}void wait_for_2fork(int no)
{unsigned short left = no;//哲学家左边刀叉号码unsigned short right = (no + 1) % 5;//哲学家右边刀叉号码struct sembuf buf[2] ={{left, -1, 0},//信号量序号、信号量的计数值减1{right, -1, 0}};semop(semid, buf, 2);
}void free_2fork(int no)
{unsigned short left = no;unsigned short right = (no + 1) % 5;struct sembuf buf[2] ={{left, 1, 0},{right, 1, 0}};semop(semid, buf, 2);
}void philosopere(int no)//哲学家行为
{srand(getpid());for (; ;){printf("%d is thinking\n", no);//思考sleep(DELAY);printf("%d is hungry\n", no);//饿wait_for_2fork(no);//获取刀叉printf("%d is eating\n", no);//进食sleep(DELAY);free_2fork(no);//释放刀叉
/* 死锁--int left = no;//哲学家左边刀叉号码int right = (no + 1) % 5;//哲学家右边刀叉号码printf("%d is thinking\n", no);//思考sleep(DELAY);printf("%d is hungry\n", no);//饿wait_1fork(left);//看到空余的刀叉立刻拿起来sleep(DELAY);wait_1fork(right);printf("%d is eating\n", no);//进食sleep(DELAY);free_2fork(no);//释放刀叉
*/}
}
int main(void)
{semid = semget(IPC_PRIVATE, 5, IPC_CREAT | 0666);//创建5把刀叉资源信号集if (semid == -1)ERR_EXIT("semget");union semun su;su.val = 1;int i;for (i = 0; i < 5; i++)//将5把刀叉都置为可用状态{semctl(semid, i, SETVAL, su);//将信号集中每个信号量初始值都置为1,表示可用}int no = 0;//开始5个哲学家就坐(5个进程)pid_t pid;for (i = 1; i < 5; i++)//创建4个子进程{pid = fork();if (pid == -1)ERR_EXIT("fork");if (pid == 0)//说明是子进程{no = i;break;}}philosopere(no);//每个(进程)哲学家的行为return 0;
}

数据结果如下:

1 is thinking
2 is thinking
0 is thinking
4 is thinking
3 is thinking
3 is hungry
3 is eating
0 is hungry
0 is eating
1 is hungry
4 is hungry
2 is hungry
0 is thinking
1 is eating
3 is thinking
4 is eating
1 is thinking
2 is eating

std::lock_guard使用案例及常用系统函数调用案例相关推荐

  1. Dos系统常用命令【案例---计算机快捷助手】

    Dos系统常用命令[案例-计算机快捷助手] Dos系统是基于磁盘管理的操作系统,与我们现在常用的操作系统,如win7.win10等操作系统有很大的区别,没有可视化的图形界面,而是通过命令行的形式进行交 ...

  2. PHP常用系统函数帅哥特供版

    [TOC] PHP常用系统函数帅哥特供版 常用操作 定界符 <<<EOF内容EOF; 1.PHP定界符的作用就是按照原样,包括换行格式什么的,输出在其内部的东西: 2.在PHP定界符 ...

  3. C++中的std::lock_guard和std::unique_lock

    std::lock_guard 这是最简单的一个管理锁的对象.只有构造和析构函数,在构造的时候加锁,析构的时候解锁,解锁后就不能使用该对象再加锁了.可以避免使用std::mutex时忘记解锁的情况,同 ...

  4. Java中构造方法的案例及常用类int lenght类的使用方法举例,new实例化对象方法,静态方法实例方法的举例

    目录 一.前言 二.构造方法的案例 2.1代码部分 2.2运行截图 三.常用类int lenght类的使用方法举例 3.1程序代码 3.2运行结果 四.new实例化对象方法例题 4.1程序代码 4.2 ...

  5. python123测试3平方根格式化_Python3常用系统函数帅哥定制版

    Python3常用系统函数JSON帅哥定制版 没错,这里的帅哥指的就是我自己 安装 安装pip3 wget --no-check-certificate https://pypi.python.org ...

  6. Python3常用系统函数帅哥定制版

    Python3常用系统函数JSON帅哥定制版 没错,这里的帅哥指的就是我自己 安装 安装pip3 wget --no-check-certificate https://pypi.python.org ...

  7. 【科研数据处理建模】SPSS实战操作生成36类常用论文研究案例,供学习参考

    SPSS实战操作 0 注意事项 1 描述性统计 1.1 频数分析表 案例1 1.2 交叉分析表 案例2 1.3 分组汇总 案例3 2 假设检验 2.1 正态性检验 案例4 2.2 单样本比率检验 案例 ...

  8. 分享一个工业现场常用的运动控制案例

    自动化行业,正在慢慢往软件行业靠近. 很多PLC工程师也开始慢慢意识到,掌握一门编程语言,变得越来越重要. 那么PLC工程师学会编程之后,会是一种什么样的体验? 我觉得最直接的体验就是:原理性的东西懂 ...

  9. C++11中std::lock_guard的使用

    互斥类的最重要成员函数是lock()和unlock().在进入临界区时,执行lock()加锁操作,如果这时已经被其它线程锁住,则当前线程在此排队等待.退出临界区时,执行unlock()解锁操作.更好的 ...

最新文章

  1. 【Android 基础】Animation 动画介绍和实现
  2. 用Python抓取某东购买记录并统计MM的bra大小
  3. html 链接 pdf,简单的HTML DOM只解析名称和含有PDF链接链接
  4. Linux如何关机与关机命令祥解
  5. FlinkShell用kill -9杀不掉
  6. python数据统计代码_Python 数据的累加与统计的示例代码
  7. [Usaco2010 Mar]gather 奶牛大集会
  8. python中excel制作成绩报表_python制作简单excel统计报表2之操作excel的模块openpyxl简单用法...
  9. 三、 将DataTable 转换为List
  10. 【代码+论文】基于自适应排序学习的个性化推荐方法
  11. Linux使用命令记录
  12. java中将zip文件解压到指定目录下
  13. STM32单片机编译器Keil环境配置教程
  14. 虚幻4和Unity3D应该学哪个?
  15. 51单片机 简易秒表计时器(100秒) 小数点后四位
  16. 《Windows办公指南》魔改C:\Windows\System32\drivers\etc\hosts实现一个数据中心
  17. 暴力递归到动态规划 05 (贴纸拼词)
  18. 打造你的“私人空间”,玩客云详细评测
  19. 有趣的灵魂用有趣的屏保SadMac.saver
  20. onMouse 鼠标移入移出事件

热门文章

  1. c4a服务器型号,购买服务器主机做C4D
  2. Games102 学习笔记
  3. ESP8266--驱动DS18B20
  4. 川崎机器人f控制柜接线图_plc控制柜接线图讲解 plc电气柜接线图解入门
  5. 极限编程的幻想与真实
  6. IDEA常用快捷键和谷歌浏览器快捷键Mac版
  7. 4款安装后就不打算卸载的“神器”APP,每天浪费时间在这上面也觉得值
  8. python操作office_Python_13-Office文件数据操作
  9. 提升串口服务器的稳定性,带DTU功能的十六串口服务器
  10. 新浪时金php面试题,关于面试PHP常见的面试试题