zoukankan      html  css  js  c++  java
  • 多线程笔试

    1、首先考虑,什么情况下使用多线程?

      第一种情况:做事情A的过程中,顺便去做事情B,不需要B完成,可以接着做A余下的部分。这种情况下,对于事情B启动一个线程,往往需要传入一个回调方法,等事情B完成后,在主线程上执行回调方法。

      第二种情况:事情A和事情B同时做,他们访问同一块数据,需要对这块数据加锁。

    2、考虑下面的需求,两个线程t1,t2,修改同一个数据,t1每次增加1,t2每次减2,怎么做?

      a、首先肯定要准备两个方法Add1和Sub2,分别传给t1,t2;

      b、准备共享资源和互斥体mutex(也就是值为1 的信号量);

      c、Add1和Sub2方法内分别加锁,在加锁的语句块内,修改共享资源。

    3、上面的需求,只要求一个一个访问,并没有要求t1和t2之间进行一定的协作。考虑下面的需求,t1,t2轮流打印,t1打印1,t2打印2,t1打印3,t2打印4,。。。。该怎么办?

      a、当然第一步,还是必须要准备两个方法,PrintOdd和PrintEven;

      b、准备共享资源和互斥体mutex;

      c、Add1和Sub2方法内分别加锁,在加锁的语句块内,修改共享资源。

      特别注意的是:这种情况下,加锁成功后,修改共享资源之前,必须检查修改的前提条件是否满足。也就是说,按道理轮到自己了,但是还必须要检查前提条件是否满足,如果不满足,这次把锁释放,继续下一次申请加锁。

      那么,这里就有问题了。加锁成功后,前提条件不满足,不能修改,并且要释放锁。有没有更好的办法呢?

      先看前提条件是否满足,不满足,不去申请加锁,因为就算加锁成功,也不能修改,没意义。

      如果前提条件满足的话,才去申请加锁。特别注意的是:在加锁的语句中,需要再次检查前提条件,为什么?考虑这种极端情况,条件满足,去申请加锁,在申请加锁,到加锁成功这段时间内,假如其他线程修改了共享资源,可能导致前提条件又不满足了。因此,这里必须再次检查前提条件。

      1 #include <iostream>
      2 #include <stdlib.h>
      3 #include <boost/thread.hpp>
      4 #include <boost/date_time/posix_time/posix_time.hpp>
      5 
      6 using namespace std;
      7 
      8 int num = 0;
      9 boost::mutex me;
     10 void Add1()
     11 {
     12  int i=0;
     13  while(i<10)
     14  {
     15   me.lock();
     16   {
     17    num = num+1;
     18    cout<<"Add1:"<<num<<endl;
     19   }
     20   me.unlock();
     21   i++;
     22   boost::this_thread::sleep(boost::posix_time::millisec(50));
     23  }
     24 }
     25 
     26 void Sub2()
     27 {
     28  int i=0;
     29  while(i<10)
     30  {
     31   me.lock();
     32   {
     33    num = num-2;
     34    cout<<"Sub2:"<<num<<endl;
     35   }
     36   me.unlock();
     37   i++;
     38   boost::this_thread::sleep(boost::posix_time::millisec(100));
     39  }
     40 }
     41 
     42  
     43 
     44 void printOdd()
     45 {
     46  while(num<20)
     47  {
     48   //me.lock();
     49   //if(num%2==0)
     50   //{
     51   // cout<<"Odd:"<<++num<<endl;
     52   //}
     53   //me.unlock();
     54 
     55   if(num%2==0)
     56   {
     57    me.lock();
     58    if(num%2==0)
     59    {
     60     cout<<"Odd:"<<++num<<endl;
     61    }
     62    me.unlock();
     63   }
     64   boost::this_thread::sleep(boost::posix_time::millisec(50));
     65  }
     66 }
     67 
     68 
     69 void printEven()
     70 {
     71  while(num<20)
     72  {
     73   //me.lock();
     74   //if(num%2==1)
     75   //{
     76   // cout<<"Even:"<<++num<<endl;
     77   //}
     78   //me.unlock();
     79 
     80   if(num%2==1)
     81   {
     82    me.lock();
     83    if(num%2==1)
     84    {
     85     cout<<"Even:"<<++num<<endl;
     86    }
     87    me.unlock();
     88   }
     89   boost::this_thread::sleep(boost::posix_time::millisec(100));
     90  }
     91 }
     92 
     93 
     94 int _tmain(int argc, _TCHAR* argv[])
     95 {
     96  //boost::thread t1(Add1);
     97  //boost::thread t2(Sub2);
     98 
     99  boost::thread t1(printOdd);
    100  boost::thread t2(printEven);
    101 
    102  t1.join();
    103  t2.join();
    104 
    105  system("pause");
    106  return 0;
    107 }
  • 相关阅读:
    VirtualBox 收缩 vdi镜像文件
    虚拟机安装Lubuntu
    做一个平均数,合计数的sql查询
    postgersql 中 字段名,表名,命名大小写问题(原创)
    你人生中的那口井挖了没有?(转潇湘隐者)
    【智能无线小车系列十一】智能小车一体化测试
    【智能无线小车系列二】车体的组装
    【智能无线小车系列一】物品采购
    【智能无线小车系列十】通过USB摄像头实现网络监控功能
    【智能无线小车系列九】在树莓派上使用USB摄像头
  • 原文地址:https://www.cnblogs.com/nzbbody/p/3560101.html
Copyright © 2011-2022 走看看