C++ 多线程同步问题?
#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <mutex>
#include <condition_variable>
#include <map>
#include <ctime>
#include <random>
#include <chrono>
#include <unistd.h>

#define NUM_OF_SAMPLES 50
#define MAX_NUM_OF_THREADS 6

using namespace std;

class Sensor {
private:
    string sensorType;

public:
    Sensor(string& type) : sensorType(type){}

    //Declare a virtual method to be overridden by derived classes:
    virtual double getValue() = 0;

    //Declare non-virtual method:
    string getType() {
        return sensorType;
    }
};

class TempSensor : public Sensor {
public:
    TempSensor(string& s) : Sensor(s) {}

    double getValue() {
        return (double)rand() / ((double)RAND_MAX / 20) + 10;
    }
};

class PressureSensor : public Sensor {
public:
    PressureSensor(string& type) : Sensor(type) {}

    double getValue() {
        return (double)rand() / ((double)RAND_MAX / 10) + 95;
    }
};

class CapacitiveSensor : public Sensor {
public:
    CapacitiveSensor(string& type) : Sensor(type) {}

    double getValue() {
        return (double)rand() / ((double)RAND_MAX / 4) + 1;
    }
};

class BC {
private:
    bool lock = false; //'false' means that the BC is not locked
    vector<Sensor *>& theSensors; //reference to vector of Sensor pointers
    mutex BC_mu;
    condition_variable cv;
    map<int, string> sensorMap;
    map<int, int> countMap;

public:
    BC(vector<Sensor *>& sensors) : theSensors(sensors) {
        sensorMap.insert(pair<int, string>(0, "temperature"));
        sensorMap.insert(pair<int, string>(1, "pressure"));
        sensorMap.insert(pair<int, string>(2, "capacitive"));
    }

    void requestBC(int index) {
        unique_lock<mutex> lk(BC_mu);
        if (lock) {
            cout << "BusController is locked, thread " << index << " is about to suspend.." << endl;
            cv.wait(lk);
        }
        lock = true;
        cout << " BusController locked by thread " << index << endl;
        return;
    }

    double getSensorValue(int selector) {
        countMap[selector]++;
        return theSensors[selector]->getValue();
    }

    void releaseBC(int index) {
        unique_lock<mutex> lk(BC_mu);
        lock = false;
        cout << "BusController unlock by thread " << index << endl;
        cv.notify_one();
    }

    string getSensorType(int selector) {
        return sensorMap[selector];
    }

    void printCntSensorType() {
        for (auto it = countMap.begin(); it != countMap.end(); it++) {
            cout << sensorMap[it->first] << " accessed " << it->second << " times" << endl;
        }
    }
};


void run(BC& theBC, int index) {
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis1(0, 2);
    uniform_int_distribution<> dis2(1000, 10000);

    for (int i = 0; i < NUM_OF_SAMPLES; i++) {
        theBC.requestBC(index);
        int sensorTypeIndex = dis1(gen);
        string sensorStr = theBC.getSensorType(sensorTypeIndex);
        double randSensorValue = theBC.getSensorValue(sensorTypeIndex);
        cout << "       sample value from thread " << index << " from " << sensorStr << " sensor = " << randSensorValue << endl;
        theBC.releaseBC(index);
        usleep(dis2(gen));
     }
}

int main() {
    vector<Sensor *> sensors;
    string temp = "temperature", pressure = "pressure", capa = "capacitive";
    sensors.push_back(new TempSensor(temp));
    sensors.push_back(new PressureSensor(pressure));
    sensors.push_back(new CapacitiveSensor(capa));

    BC theBC(ref(sensors));
    thread theThreads[MAX_NUM_OF_THREADS];
    for (int i = 0; i < MAX_NUM_OF_THREADS; i++) {
        theThreads[i] = thread(run, ref(theBC), i);
    }
    for (int i = 0; i < MAX_NUM_OF_THREADS; i++) {
        theThreads[i].join();
    }
    theBC.printCntSensorType();
    return 0;
}

代码如上所示,主要实现的功能是六个线程去抢占BC类,然后选择不同的sensor进行输出,但是BC类中关于线程的同步机制觉得存在问题,求大神指导。

0

1个回答

0
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
C语言 多线程使用说明3-线程同步问题引入
先开一个坑吧。。哎,线程真是老火。 在实际生活中售卖火车票室友多个站点的,所以在火车站的售卖系统一定是用多线程操作来实现的,接下来我们编写简单的火车票系统,当然,简单的意思就是非常辣鸡。 #include &quot;stdafx.h&quot; #include &amp;lt;string.h&amp;gt; #include &amp;lt;stdio.h&amp;gt; #include &amp;lt;stdlib.h&amp;gt; #inclu...
三种方式实现多线程同步问题
1使用互斥量和事件对象实现线程同步的代码 #include #include DWORD WINAPI Fun1Proc( LPVOID lpParameter // thread data ); DWORD WINAPI Fun2Proc( LPVOID lpParameter // thread data ); int tickets = 100; //HANDLE
Linux下C/C++ 多线程同步
#include &amp;lt;pthread.h&amp;gt; #include &quot;PosixMutexLock.hpp&quot;   #ifndef POSIX_SYNC #define POSIX_SYNC class PosixSync  { private:   protected:   PosixMutexLock *lock;   pthread_cond_t block;...
多线程同步机制,锁的必要条件
创建       在同一个进程中的多线程是处于同一个地址空间内,即只要知道一个线程的地址,就能够在另一个线程中访问该地址的内容,本文即介绍同一个进程中的多线程使用方式。       C++创建多线程指定线程的启动函数和传递参数不同。可以给pthread_create函数传递C++类的静态成员函数和该类的对象指针,因为在不同线程之间的地址是处于同一个地址空间内,所以其他线程也可以访问到。从而通过这种...
多核、多处理器环境下多线程同步技巧
多核、多处理器环境下多线程同步技巧,来自CocoaChina。 我们这里大部分人应该已经熟悉了在单核单处理器的环境下对多线程进行同步的方法。传统的方法有:Mutex(互斥体)、Semaphore(信号 量)、Event(事件)、MailBox(邮箱)、Message(消息)等。这些方法都有个共同的特性——即在使用这些方法的前、后会分别加 上关中断、开中断操作(或是任务调度的禁止、开启
volatile能实现多线程同步吗???NO
Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了同步块 和 volatile 关键字机制。 用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。但是volatile并不能进行原子性操作。 举个例子: package com.blog.fenye; public class Counts { public static int c
C-多线程读写同步
网易公开课,多线程读写同步,VS2010控制台程序: // testVC.cpp : 读写同步实现。 // #include "stdafx.h" #define BUFFLENGTH 8 char buffer[BUFFLENGTH]; HANDLE hSemaphoreEmpty; HANDLE hSemaphoreFull; DWORD _stdcall Reader(L
IOS多线程同步问题
IOS开发多线程开发,同步块,NSLock,NSCondition
多线程同步解决卖票问题
。。。。。。。多线程同步解决卖票问题
linux中c多线程同步方法
线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点。linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量和信号量。 一、互斥锁(mutex) 通过锁机制实现线程间的同步。 初始化锁。在Linux下,线程的互斥量数据类型是pthread_mutex_t。在使用前,要对它进行初始化。 静态分配:pthread_mutex_t mutex = PTHREAD_...
Java基础之多线程的5个经典同步问题
本文转载之http://blog.csdn.net/naruto_ahu/article/details/86723761. 生产者-消费者问题也叫缓存绑定问题(bounded- buffer),是一个经典的、多进程同步问题。即有两个进程:制造商和消费者,共享一个固定大小的缓存。制造商的工作是制造一段数据,放进缓存,如此反复。同时,消费者则一次消费一段数据(即将其从缓存中移出)。问题的核心就是要保...
【Linux多线程】同步与互斥的区别
很多人把同步与互斥这两个概念混淆,这里说一下它们的区别。一、同步与互斥的区别1. 同步同步,又称直接制约关系,是指多个线程(或进程)为了合作完成任务,必须严格按照规定的 某种先后次序来运行。例如,线程 T2 中的语句 y 要使用线程 T1 中的语句 x 的运行结果,所以只有当语句 x 执行完成之后语句 y 才可以执行。我们可以使用信号量进行同步:semaphore S=0; // 初始化信号量T
Linux下线程同步的几种常见方法
Linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量和信号量。一、互斥锁(mutex)  锁机制是同一时刻只允许一个线程执行一个关键部分的代码。 1. 初始化锁  int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);   其中参数 mutexattr 用于指定锁的属...
Linux多线程同步的几种方式
线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点。linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量和信号量。 1)互斥锁(mutex)     通过锁机制实现线程间的同步。同一时刻只允许一个线程执行一个关键部分的代码。 int pthread_mutex_init(pthread_mutex_t *mutex,const pthrea
Windows下C/C++ 多线程同步
#include &quot;Lock.hpp&quot; #include &quot;EventLock.hpp&quot;   #ifndef __SYNC #define __SYNC class Sync  { private:   protected:   EventLock *lock;   EventLock *block;   public:   Sync();   void w...
多线程实现同步的七种方式
JAVA中线程同步的方法(7种)汇总 同步的方法: 一、同步方法   即有synchronized关键字修饰的方法。 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。 注: synchronized关键字也可以修饰静态方法,此时如果调
ndk开发之多线程同步与通信
在进行android的ndk开发时,耗时任务会用到native子线程。在pthread头文件中定义有创建子线程、互斥锁、条件变量等相关方法。线程同步是利用互斥锁(mutex)与条件(condition)变量的结合,经常出现于生产者与消费者模式场景中。先定义相关变量:#include &amp;lt;pthread.h&amp;gt; //生产者线程 pthread_t thread_product; //消费者线...
多线程同步的几种实现方法
多线程同步的几种实现方法,synchronized wait与notify
C++多线程-第五篇-同步机制
Call_once 使用call_once包装的函数在多线程中只会被执行一次。 Void call_once(once_flag&flag, Callable && func,Args &&.....args); 其中once_flag 声明必须是线程安全的,可采用static.且不可使用临时变量给Call_once.     条件变量--同步机制 需要和互斥量配合使用。 Thre
Linux — 浅析线程以及多线程的同步与互斥
线程 链接:http://blog.csdn.net/ctthuangcheng/article/details/8914712 关于linux线程 在许多经典的操作系统教科书中, 总是把进程定义为程序的执行实例, 它并不执行什么, 只是维护应用程序所需的各种资源. 而线程则是真正的执行实体. 为了让进程完成一定的工作, 进程必须至少包含一个线程. 如
C++线程同步的几种方式
1.临界区,通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。确保在某个时刻只有一个线程能访问数据。此时其他线程如想访问数据则会被挂起,直到当前线程离开临界区。临界区被释放后,其他线程继续抢占。 2.互斥量,和临界区类似,可以保证同一时刻只有一个线程访问数据。类似java中的对象锁。成功获取互斥量的线程可以访问数据,其他线程将被挂起,直到当前线程释放互斥量。互斥量比临界区复...
【Linux多线程】三个经典同步问题
在了解了《同步与互斥的区别 》之后,我们来看看几个经典的线程同步的例子。相信通过具体场景可以让我们学会分析和解决这类线程同步的问题,以便以后应用在实际的项目中。一、生产者-消费者问题问题描述:一组生产者进程和一组消费者进程共享一个初始为空、大小为 n 的缓冲区,只有缓冲区没满时,生产者才能把消息放入到缓冲区,否则必须等待;只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,
Linux下的多线程编程——同步互斥问题(互斥锁)
互斥锁什么是互斥锁:互斥锁是用来保证同一时间内某段代码只能由一个线程执行。互斥锁的声明:pthread_mutex_t mutex; 互斥锁初始化函数:pthread_mutex_init( &amp;amp;mutex, NULL); 加锁函数:int pthread_mutex_lock(pthread_mutex_t *mutex); 解锁函数:int pthread_mutex_unlock(pt...
C语言多线程编程-死锁和线程同步方式介绍(一)
线程同步,互斥锁,条件变量,读写锁
Linux C线程同步的三种方法
线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点。linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量和信号量。一、互斥锁(mutex)通过锁机制实现线程间的同步。初始化锁。在Linux下,线程的互斥量数据类型是pthread_mutex_t。在使用前,要对它进行初始化。静态分配:pthread_mutex_t mutex = PTHREAD_MUTEX_IN...
C++实现多线程及其三种方法实现多线程同步
1.调用windows API实现多线程 #include "stdafx.h" #include #include #include DWORD WINAPI myfun1(LPVOID lpParameter); //声明线程函数 DWORD WINAPI myfun2(LPVOID lpParameter); using namespace std; int _tmain(in
多线程间的同步与互斥
多线程与临界区 多线程想要访问临界区时,就要对临界区进行上锁,这与之前写到的进程互斥是一个道理,这也就是防止共享数据被并发访问的解决方法,这种上锁叫做互斥锁 互斥锁 互斥锁以排他的方式保护共享数据被并发访问。 因为在线程中,内存地址空间是共享的,就像一个大房子,在这个进程中的线程们都可以进来,当我们某一个线程想做一些事时,不想让其他线程打断,那我们就给门上加个锁,当一个进程进来后,...
10分钟,带你掌握C++多线程同步!
摘要:本文介绍了C++11中如何开启新线程,并详细讲解了线程的基础同步原语:mutex, lock_guard, unique_lock, condition variable和semaphore等。如何采用async,  packaged_task和promise实现future同步机制?怎样处理spurious wakeup?本文以质数判定服务为例为大家分享C++多线程同步措施!   数十...
java中的多线程和数据同步问题
编程中有一个经典的多线程问题:有两个线程,一个负责写入数据,一个负责读出数据,当两个线程同步运行时,如何保证数据的准确性和安全性?人们将这一问题抽象成生产者-消费者模型。 //有一个数据模型Person类,包含三个属性以及写入和读取这三个属性的方法。 public class Person { private String name; private String gender; p...
C++中多线程面试经典问题
1、基本概念         详见:线程和进程关系和区别、同步和互斥、进程间通信 2、以下多线程对int型变量x的操作,哪几个不需要进行同步(D)         A. x=y;      B. x++;    C. ++x;    D. x=1;         详见:多线程二 多线程中的隐蔽问题揭秘 3、多线程中栈与堆是公有的还是私有的 (C)        
linux多线程编程——同步与互斥
我们在前面文章中已经分析了多线程VS多进程,也分析了线程的使用,现在我们来讲解一下linux多线程编程之同步与互斥。 现在,我们不管究竟是多线程好还是多进程好,先讲解一下,为什么要使用多线程? 一、 为什么要用多线程技术? 1、避免阻塞,大家知道,单个进程只有一个主线程,当主线程阻塞的时候,整个进程也就阻塞了,无法再去做其它的一些功能了。 2、避免CPU空转,应用程序经常会涉及到RPC,数
C++线程同步的四种方式(Windows)
为什么要进行线程同步?  在程序中使用多线程时,一般很少有多个线程能在其生命期内进行完全独立的操作。更多的情况是一些线程进行某些处理操作,而其他的线程必须对其处理结果进行了解。正常情况下对这种处理结果的了解应当在其处理任务完成后进行。   如果不采取适当的措施,其他线程往往会在线程处理任务结束前就去访问处理结果,这就很有可能得到有关处理结果的错误了解。例如,多个线程同时访问同一个全局变量,如果都是
多线程同步——哲学家吃饭问题
最近在学习多线程编程(WIN32API下和C++11标准),学习过程中想起了在学操作系统的时候出现过的“哲学家吃饭问题”,当时听得云里雾里的,理解并不算透彻。恰好最近在学习多线程同步的知识,恰好可以利用最近所学模拟一下这个过程。一、问题描述二、问题分析哲学家就餐问题需要协调考虑两个问题:1、不能让某个哲学家饿死;2、要尽量提升吃饭的效率,也就是同一时间尽量让多一些哲学家吃饭(最多同时两个)。我们考...
【java 多线程】多线程并发同步问题及生产者、消费者问题
一、线程并发同步概念 线程同步其核心就在于一个“同”。所谓“同”就是协同、协助、配合,“同步”就是协同步调昨,也就是按照预定的先后顺序进行运行,即“你先,我等, 你做完,我再做”。 线程同步,就是当线程发出一个功能调用时,在没有得到结果之前,该调用就不会返回,其他线程也不能调用该方法。 就一般而言,我们在说同步、异步的时候,特指那些需要其他组件来配合或者需要一定时间来完成的任务。
【JNI编程】JNI中进行线程同步
JVM可以做到在相同的地址空间内执行多个线程。由于多个线程可能会在同时共享资源,所以,增加了程序的复杂性。 一、预备知识 1.1 约束限制 如果你的本地代码要运行在多个线程中,有一些约束条件需要注意,这样的话,才能使得你的本地代码无论被多少个线程同时运行,都不会出现问题。 JNIEnv指针只在它所在的线程中有效,不能跨线程传递和使用。不同线程调用一个本地方法时,传入的JNIEnv指针是不同的。...
线程同步的几种实现方法
一、引言 前几天面试,被大师虐残了,好多基础知识必须得重新拿起来啊。闲话不多说,进入正题。 二、为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常。举个例子,如果一个银行账户同时被两个线程操作,一个取100块,一个存钱100块。假设账户原本有0块,如果取钱线程和存钱线程同时发生,
java多线程同步分析
java多线程同步分析java多线程同步分java多线程同步分析析java多线程同步分析java多线程同步分析
java多线程同步的五种方法
一、前几天去面试,被大师问道一些很基础的问题,感觉自己答的很不满意,闲话不多说,进入正题.二、为什么要使用同步? 因为当我们有多个线程要同时访问同一个变量或对象时,如果这些线程中午既有读又有写操作时,就会导致变量值或者对象的状态出现混乱,从而导致程序异常,举个例子:如果同一个银行账户被连个线程操作,一个存钱1000.00,一个取1000.00,假设该账户原本为金额为0.00,如果取钱线程和
VS C++ 线程篇之线程同步
线程同步解决        不同线程函数的执行顺序,进行线程协调。  APIDWORD WINAPI WaitForSingleObject( HANDLE hHandle, // 对象句柄 Thread/Event/Job/Mutex/Process/Semaphore/Waitable timer/Memory resource notification DWORD dwMillisec...
多线程同步和互斥有哪几种实现方法?
点击打开原文链接线程间的同步方法大体可分为两类:用户模式和内核模式。顾名思义,内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,而用户模式就是不需要切换到内核态,只在用户态完成操作。用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。内核模式下的方法有:事件,信号量,互斥量。1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问...
文章热词 设计制作学习 机器学习教程 Objective-C培训 交互设计视频教程 颜色模型
相关热词 mysql关联查询两次本表 native底部 react extjs glyph 图标 区块链问题 大数据专业教育的问题