0

I have a couple of classes here that I would like to remove window library dependencies for portability reasons. One for blocking processes and the other for blocking threads. Both of these classes compile & runs fine as is... As for the BlockProcess class it is currently using a HANDLE for a mutex and using function calls such as: {CreateMutex(), CloseHandle() & GetLastError()}. As for the BlockThread class it uses a pointer to a CRITICAL_SECTION calling functions such as: {EnterCricticalSection() & LeaveCriticalSection()}.

What I would like to know is there an equivalent way to do this using something from the std library such as std::mutex, std::thread etc. that will provide the same functionality. I would like to remove the need to have #include<windows.h> & possibly #include<process.h>.

Here are my existing classes:


BlockProcess.h

#ifndef BLOCK_PROCESS_H
#define BLOCK_PROCESS_H

#include <Windows.h>
#include <process.h>
#include <string>

namespace demo {

class BlockProcess final {
private:
    HANDLE hMutex_;
public:
    explicit BlockProcess( const std::string& strName );
    ~BlockProcess();

    bool isBlocked() const;

    BlockProcess( const BlockProcess& c ) = delete;
    BlockProcess& operator=( const BlockProcess& c ) = delete;
};

} // namespace demo

#endif // !BLOCK_PROCESS_H

BlockProcess.cpp

#include "BlockProcess.h"

namespace demo {

BlockProcess::BlockProcess( const std::string& strName ) {
    hMutex_ = CreateMutex( nullptr, FALSE, strName.c_str() );
} 

BlockProcess::~BlockProcess() {
    CloseHandle( hMutex_ );
}

bool BlockProcess::isBlocked() const {
    return (hMutex_ == nullptr || GetLastError() == ERROR_ALREADY_EXISTS);
}

BlockThread.h

#ifndef BLOCK_THREAD_H
#define BLOCK_THREAD_H

#include <Windows.h>

namespace demo { 

class BlockThread final {
private:
    CRITICAL_SECTION* pCriticalSection_;

public:
    explicit BlockThread( CRITICAL_SECTION& criticalSection );
    ~BlockThread();

    BlockThread( const BlockThread& c ) = delete;
    BlockThread& operator=( const BlockThread& c ) = delete;
}; 

} // namespace demo

#endif // !BLOCK_THREAD_H


} // namespace demo

BlockThread.cpp

#include "BlockThread.h"

namespace demo { 

BlockThread::BlockThread( CRITICAL_SECTION& criticalSection ) {
    pCriticalSection_ = &criticalSection;
    EnterCriticalSection( pCriticalSection_ );
} 

BlockThread::~BlockThread() {
    LeaveCriticalSection( pCriticalSection_ );
}

} // namespace demo

Edit

If you need an example of how these classes are used feel free to leave a comment.

Francis Cugler
  • 7,788
  • 2
  • 28
  • 59

2 Answers2

2

Your BlockThread is essentially std::lock_guard (to be used over an std::mutex instead of CRITICAL_SECTION). It can be trivially replaced with standard library code.

As for BlockProcess (creation of a cross-process synchronization object), there's no standard equivalent.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • 1
    `#include #include #include ` are all useful includes for cross platform threading. – aj.toulan Jan 25 '18 at 19:09
  • Okay I think that kind of makes sense now. For blocking threads there is a similar mechanism in the library, but as for `processes` because they are `machine - os` dependent there is no `standard` way as they are platform specific. – Francis Cugler Jan 25 '18 at 19:09
  • To block a processes, you'll need to use `#include std::condition_variable` in combination with you mutex to make a process wait. – aj.toulan Jan 25 '18 at 19:13
  • So with the current `BlockProcess` class I'm still inclined to have to `#include` for declaring a `HANDLE` and using `CreateMutex()` and `CloseHandle()`... – Francis Cugler Jan 25 '18 at 19:14
  • All you need is `std::mutex locker;` to create a mutex. Here is a good example. http://www.cplusplus.com/reference/condition_variable/condition_variable/wait/ – aj.toulan Jan 25 '18 at 19:15
  • @FrancisCugler: well, it's not written in the stone - even threads required platform specific code before C++11, but eventually they standardized a common interface. But yes, as for now the C++ standard provides no facility to manage processes. – Matteo Italia Jan 25 '18 at 19:15
  • @aj.toulan The functionality with the `BlockProcess` class here is that the `string` it takes is the name of the currently running executable. If you pass that string to the constructor of this class and then in an `if statement` you call to check to see if `isBlocked()` returns true or not from there if the executable is already running in memory, I typically will throw an exception. Its to prevent multiple running occurrences of the same application. – Francis Cugler Jan 25 '18 at 19:16
  • 1
    @aj.toulan: the classes you are citing can be used for cross thread synchronization, not cross process. – Matteo Italia Jan 25 '18 at 19:17
  • @MatteoItalia The 2 classes are `Independent` of each other. The one for `BlockProcess` is used to prevent multiple simultaneously running instances of the same executable. For the `BlockThread` it is to help with `synchronization` across multiple threads. – Francis Cugler Jan 25 '18 at 19:19
  • 1
    @FrancisCugler: yes, I'm aware of that, in facts as I wrote in my answer you can replace `BlockThread` but not `BlockProcess`. I was just trying to explain it to aj.toulan. – Matteo Italia Jan 25 '18 at 19:20
  • @MatteoItalia Ah okay, my apologies about the confusion; I overlooked the fact that you directed the comment towards another user... – Francis Cugler Jan 25 '18 at 19:22
  • Oh, you're right! I'm sorry, I jumped the gun! I've done more C++ on windows but more threading C++ coding on unix. I should have read more carefully. – aj.toulan Jan 25 '18 at 19:23
  • 2
    So typically with `Threading` you can remove platform specific code, but as for `Processes` your left at the mercy of the OS... – Francis Cugler Jan 25 '18 at 19:24
2

boost interprocess does offer cross-platform inter-process synchronization objects (akin to the inter-thread objects of the standard library). But the standard library types are purely in-process.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23