1. 死锁与解锁:

#include <iostream>
#include <thread>
#include <mutex> using namespace std; //thread引用类型函数,模板,避免类型转换,尽量指针,引用
//锁住一个变量之后,尽快操作完解锁,不要再锁,否则互锁
#define COUNT 100000
mutex g_mutex1, g_mutex2;//互斥量 void add1(int *p1, int *p2)
{
for (int i = ; i < COUNT; i++)
{
/*g_mutex1.lock();
p1++;
g_mutex2.lock();
p2++;
g_mutex1.unlock();
g_mutex2.unlock();*/ g_mutex1.lock();
(*p1)++;
g_mutex1.unlock(); g_mutex2.lock();
(*p2)++;
g_mutex2.unlock();
}
}
void add2(int *p1, int *p2)
{
for (int i = ; i < COUNT; i++)
{
/*g_mutex2.lock();
g_mutex1.lock();
p1++;
g_mutex1.unlock();
p2++;
g_mutex2.unlock();*/ g_mutex2.lock();
(*p2)++;
g_mutex2.unlock(); g_mutex1.lock();
(*p1)++;
g_mutex1.unlock();
}
} void main()
{
int a = ;
int b = ; thread th1(add1, &a, &b);
thread th2(add2, &a, &b); th1.join();
th2.join(); while ()
{
cout << a << endl;
cout << b << endl;
this_thread::sleep_for(chrono::seconds()); } cin.get();
}

 2. 迅雷面试题:

  编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,

  要求输出结果必须按ABC的顺序显示。如:ABCABC...,依次递推。

    【参考答案】

//编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,
//要求输出结果必须按ABC的顺序显示。如:ABCABC...,依次递推。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable> using namespace std; int LOOP = ; //循环次数
int flag = ; //标识符 012012012012
mutex m;
condition_variable cv; void fun(int id)
{
for (int i = ; i < LOOP; i++)
{
unique_lock<mutex> ulk(m); //设定锁定
while ((id-) != flag)
{
cv.wait(ulk); //不是该出现的场合,就等待
}
cout << (char)id; //转换id flag = (flag + ) % ; //012,012,012,...
cv.notify_all(); //通知全部
}
} void main()
{
thread t1(fun, );
thread t2(fun, );
thread t3(fun, ); t1.join();
t2.join();
t3.join(); cin.get();
}

    运行结果:

    【分析】若题目变为:4个线程,输出结果要求为: ABCDABCDABCD...又该如何做呢?

//编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,
//要求输出结果必须按ABC的顺序显示。如:ABCABC...,依次递推。 #include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable> using namespace std; int LOOP = ; //循环次数
int flag = ; //标识符 012012012012
mutex m;
condition_variable cv; void fun(int id)
{
for (int i = ; i < LOOP; i++)
{
unique_lock<mutex> ulk(m); //设定锁定
while ((id-) != flag)
{
cv.wait(ulk); //不是该出现的场合,就等待
}
cout << (char)id; //转换id flag = (flag + ) % ; //012,012,012,...
cv.notify_all(); //通知全部
}
} void main()
{
thread t1(fun, );
thread t2(fun, );
thread t3(fun, );
thread t4(fun, ); t1.join();
t2.join();
t3.join();
t4.join(); cin.get();
}

    运行结果:

3. 思考:上题中若变为开启5个线程,ID分别为1,2,3,4,5,每个线程将自己的ID在屏幕上打印10遍,要求输出结果为:12345,54321,12345,54321,...依此类推。

4. 线程交换 swap:

#include <iostream>
#include <thread>
using namespace std; void main()
{
thread t1([]() {cout << "ZhangShan"<<endl; });
thread t2([]() {cout << "LiSi"<<endl; }); cout << "t1.get_id():" << t1.get_id() << " t2.get_id():" << t2.get_id() << endl; swap(t1, t2); //交换句柄 cout << "t1.get_id():" << t1.get_id() << " t2.get_id():" << t2.get_id() << endl; t1.join();
t2.join(); cin.get();
}

5. 线程移动 move:

#include <iostream>
#include <thread>
#include <cstdlib> using namespace std; void main()
{
thread t1([]()
{
int i = ;
while ()
{
i++;
if (i > )
{
break;
}
}
cout << i << endl;
system("pause");
}); cout << "t1:" << t1.get_id() << endl; //6872
//t1.join();
thread t2 = move(t1);//线程移动,t2具备了t1的属性,t1挂了
cout << "t1:" << t1.get_id() << endl; //
cout << "t2:" << t2.get_id() << endl; // t2.join(); cin.get();
}

    运行结果:

6. 线程自动加解锁:

#include <iostream>
#include <thread>
#include <mutex> using namespace std; #define N 10000000
mutex g_mutex;//全局互斥量 void add(int *p)
{
for (int i = ; i < N; i++)
{
unique_lock<mutex> ulk(g_mutex);
//没有mutex所有权,自动加锁自动解锁,根据块语句锁定
//根据mutex属性来决定,是否可以加锁 //lock_guard<mutex> lgd(g_mutex);
//拥有mutex所有权,自动加锁自动解锁
//读取mutex失败的情况下就会一直等待
(*p)++;
}
} void main()
{
int a = ; thread t1(add, &a);
thread t2(add, &a); t1.join();
t2.join(); cout << a << endl; cin.get();
}

7. 线程等待固定时间:

#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <cstdlib>
#include <ctime> using namespace std; condition_variable cv;
mutex m;
bool done=false; void run()
{
auto start = chrono::high_resolution_clock::now(); //当前时间
auto end = start + chrono::seconds(); unique_lock<mutex> ulk(m);
while (!done)
{
if (cv.wait_until(ulk, end) == cv_status::timeout)//超时
{
done = true;
break;
}
}
//this_thread::sleep_until(end); system("pause");
} void main1601()
{
thread th(run); cin.get();
} void main()
{
time_t t1, t2;
auto start = chrono::high_resolution_clock::now(); //当前时间
t1 = time(&t1); double db = ;
for (int i = ; i < ; i++)
{
db += i;
} auto end = chrono::high_resolution_clock::now(); //当前时间
t2 = time(&t2); cout << (end - start).count() << endl; //10^-9秒(ns)
cout << difftime(t2, t1) << endl; cin.get();
}

8. 多线程实现生产者、消费者:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <array>
#include <vector> using namespace std; mutex m;
condition_variable isfull, isempty;//处理两种情况
bool flag = true;//标志,消费完了就退出
vector<int> myint();//开辟10个元素 void produce(int num) //生产
{
for (int i = ; i < num; i++)
{
unique_lock<mutex> lk(m); //锁定
while (myint.size()>=)
{
isempty.wait(lk); //满了一直等待
} myint.push_back(i);//插入
cout << "生产" << i << endl;
isfull.notify_all();//通知消费者 } this_thread::sleep_for(chrono::seconds());//休眠5秒 flag = false;
} void consume() //消费
{
while (flag)
{
unique_lock<mutex> lk(m); //锁定
while (myint.size()==)
{
isfull.wait(lk);//等待
} if (flag)
{
cout << "消费" << myint[myint.size() - ] << " " << this_thread::get_id() << endl;
myint.pop_back();//剔除最后一个 isempty.notify_all();//通知生产者继续生产
}
}
} void main()
{
thread t1(consume); //消费者
thread t2(consume);
thread t3(consume); //produce(100);
thread s1(produce,);//消费者
thread s2(produce,); t1.join();
t2.join();
t3.join(); cin.get();
}

C++多线程编程二的更多相关文章

  1. Linux系统编程@多线程编程(二)

    线程的操作 线程标识 线程的ID表示数据类型:pthread_t (内核中的实现是unsigned long/unsigned int/指向pthread结构的指针(不可移植)几种类型) 1.对两个线 ...

  2. java多线程编程(二)

    1. wait 和 sleep 区别? 1.wait可以指定时间也可以不指定,sleep必须指定时间. 2.在同步中时,对cpu的执行权和锁的处理不同.  wait:释放执行权,释放锁.  sleep ...

  3. java多线程编程(二创建线程)

    1.概念           因为java是完全面向对象的,所以在java中,我们说的线程,就是Thread类的一个实例对象.所以,一个线程就是一个对象,它有自己字段和方法. 2.创建线程 创建线程有 ...

  4. Android多线程编程<二>Handler异步消息处理机制之Message

      Message(消息):       一. Message的字段:    在Android中,Message作为线程之间(主要是子线程和UI主线程之间)数据交换的载体,通过Handler去传递.它 ...

  5. C语言多线程编程二

    一. 线程通信----事件: 1.一对一模式: #include <stdio.h> #include <stdlib.h> #include <Windows.h> ...

  6. Windows下多线程编程(二)

    线程的分类 1.     有消息循环线程 MFC中有用户界面线程,从CWinThread派生出一个新的类作为UI线程类CUIThread,然后调用AfxBeginthread(RUNTIME_CLAS ...

  7. UNIX环境编程学习笔记(27)——多线程编程(二):控制线程属性

    lienhua342014-11-09 1 线程属性概括 POSIX 线程的主要属性包括 scope 属性.detach 属性.堆栈地址.堆栈大小.优先级.在头文件 pthread.h 中定义了结构体 ...

  8. 多线程编程(二)-Exchanger的使用

    Exchanger的介绍 类Exchanger的功能可以使两个线程之间传输数据. 方法exchange()的使用 package com.wjg.unit; import java.util.conc ...

  9. 多线程编程<二>

    wait()与notify(): 1 public class ThreadComDemo { 2 public static void main(String[] args) { 3 try { 4 ...

随机推荐

  1. mysql 求2个坐标之间的距离

    CREATE DEFINER=`root`@`%` FUNCTION `f_GetDistance`(lng1 DOUBLE,lat1 DOUBLE,lng2 DOUBLE,lat2 DOUBLE) ...

  2. macOS 10.13 安装Virtualbox失败

    macOS 10.13 安装Virtualbox失败 Enviroment macOS: 10.13 High Sierra virtualBox: 5.1.28 Problem descriptio ...

  3. Java 设计模式系列(二十)状态模式

    Java 设计模式系列(二十)状态模式 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式.状态模式允许一个对象在其内部状态改变的时候改 ...

  4. android 的AlertDialog对话框

    private int selectedFruitIndex = 0;  private void showMsg2() {//  Dialog alertDialog = new AlertDial ...

  5. tomcat运行为什么要依靠jdk

    问题1:为什么要装jdk 因为tomcat是用java写的,所以运行需要JRE,就是JAVA运行时刻环境,所以必须通过安装JDK来得到这个运行环境,不装JDK装JRE也行,sun的网站上有下载.但是J ...

  6. js去掉字符串前后空格的五种方法(转)

    出处:http://www.2cto.com/kf/201204/125943.html 第一种:循环检查替换[javascript]//供使用者调用  function trim(s){  retu ...

  7. jmeter 各种配置修修改(后续增加)

    1.修改物理内存  使用jmeter进行压力测试时遇到一段时间后报内存溢出outfmenmory错误,导致jmeter卡死了,先尝试在jmeter.bat中增加了JVM_ARGS="-Xmx ...

  8. Leader/Follower多线程网络模型介绍

    之前分享过<轻量级 web server Tornado代码分析>,介绍了目前我们采用nginx + tornado的方式搭建升级.配管.数据中心等各类服务组建客户端迭代体系.最近注意到, ...

  9. CAS实战のclient自定义过滤器

    我们在配置cas client肯定写过如下代码: <filter> <filter-name>CASFilter</filter-name> <filter- ...

  10. ------------------java collection 集合学习 ----小白学习笔记,,有错,请指出谢谢

    <!doctype html>java对象集合学习记录 figure:first-child { margin-top: -20px; } #write ol, #write ul { p ...