Click here to Skip to main content
15,881,757 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Create a global mutex, this will help us to identify if another instance of the same application is running, this is needed as its inter process communication. 3. Start a thread which runs continuously with a sleep of 1 sec and write "Worker thread running" onto the console. The while will be running on flag. 4. After starting the thread wait on a global event. 5. If global event is acquired, which means another instance as set this event. Set the flag at Step 3 so that the worker thread exists. 6. When passed command line is "stop" then open the event in Step 4 and set the event.

Requirement 1:

Create a C++ console application which takes the below command line argument,

    \action: "start"

Once the start command line is passed, just run the while loop with a delay of 1 sec and write some console on each interval

Example:

    while() {
    
        sleep(1000);        

    }
Requirement 2:

The same application while running should be capable to receive command line arguments like the below,

    \action: "stop"
    
When this command line,  should break the above while loop, write the console log and exit.is sent


What I have tried:

I'm not well trained in C++ programming, but as a part of a company's recruitment process, I was asked to complete this task in C++, I understand how to use a mutex to prevent additional instances loading, but that doesn't quite solve my problem. I tried finding solutions but I was too much of a beginner to understand these mutex concepts, I'm having a deadline fast approaching, if anyone can solve it out, It will be very useful for me!
Posted
Updated 21-Jan-23 14:29pm

If you cannot complete the task yourself then you obviously do not have the level of experience that this company is looking for. And if someone here provided you with a complete solution and you got the job - what then? When they gave you a real task to complete what would you do?
 
Share this answer
 
Comments
CoadyCoder 21-Jan-23 4:45am    
I'm building myself mate, but this task came in too soon for me, Along with this I was given tasks in python and Java, and I was able to do it, I'm struggling with C++, and I wanted someone to guide me so that I can help myself develop in C++, I won't be stagnant don't worry, can you help me give a solution and explain it to me?
Richard MacCutchan 21-Jan-23 5:15am    
The question itself is unclear, but you can learn about C++ mutex types at <mutex> | Microsoft Learn[^].
Richard is so right!!, you might take a project away from someone else that understands the code or have more experience than yourself, causing them harm. That been said, here is examples in C# and C++...

Using C#
using System;
using System.Threading;

class Program {
    static Mutex mutex = new Mutex(true, "MyAppName");

    static void Main() {
        if (mutex.WaitOne(TimeSpan.Zero, true)) {
            try {
                // Run the application
            } finally {
                mutex.ReleaseMutex();
            }
        } else {
            // Another instance of the application is already running
        }
    }
}


This creates a Mutex object that can be used to ensure that only one instance of the application can run at a time. The first parameter passed to the Mutex constructor is a Boolean value that indicates whether the calling thread should initially own the mutex. The second parameter is a string that is used to identify the mutex. If another instance of the application is already running and has created a mutex with the same name, the WaitOne method will return false, indicating that another instance of the application is already running.

You can use this mechanism to ensure that only one instance of your application is running at a time, and to prevent the user from accidentally starting multiple instances of the application.

Using C++
#include <windows.h>

int main() {
    HANDLE hMutex = CreateMutex(NULL, TRUE, L"MyAppName");
    if (GetLastError() == ERROR_ALREADY_EXISTS) {
        // Another instance of the application is already running
        CloseHandle(hMutex);
        return 1;
    }

    // Run the application

    ReleaseMutex(hMutex);
    CloseHandle(hMutex);
    return 0;
}


This creates a global mutex with the name "MyAppName" using the CreateMutex function. The first parameter is a pointer to a security attributes structure, which can be set to NULL. The second parameter is a Boolean value that indicates whether the calling thread should initially own the mutex. The third parameter is a string that is used to identify the mutex.

If another instance of the application is already running and has created a mutex with the same name, the GetLastError() function will return ERROR_ALREADY_EXISTS, indicating that another instance of the application is already running.

You can use this mechanism to ensure that only one instance of your application is running at a time, and to prevent the user from accidentally starting multiple instances of the application.

Note: Make sure to include the windows.h header file for the CreateMutex and ReleaseMutex functions.
 
Share this answer
 
v2
Comments
Richard MacCutchan 21-Jan-23 10:35am    
Good answer, but only 4, as the quetion is about C++.
Andre Oosthuizen 21-Jan-23 10:56am    
Oops... I have edited the code, now shows for C++ as well as C#, thanks for pointing out!
Richard MacCutchan 22-Jan-23 11:46am    
Upgraded to a 5.
CoadyCoder 21-Jan-23 13:20pm    
Thank you, Great explanation, this definitely helps me!
Andre Oosthuizen 21-Jan-23 14:04pm    
Only a pleasure!
A C++ std::mutex instance is limited to a single process; if you need cross-process mutexes, as here, you could use operating system semaphores or, under Linux, Posix mutexes in shared memory.
If the first process sets a system-wide mutex semaphore to 0, the second process could execute a sem_wait() on that semaphore and would be blocked until the mutex is removed. The command line arguments are processed before the sem_wait() and could thus send a message to the first process via IPC. If one uses non-blocking messages no threading is necessary.
If one of the processes receives the "Stop" command it could send a message to the first command and would be blocked by the mutex first. Once the first process gets the message it would have to unblock the mutex before it exits. Then the next process in the mutex queue would continue.
If you use blocking messages you would need a thread so that the output can happen every second.

// edit:
Several IPC mechanisms can be used for cross-process non-blocking data exchange. Semaphores are not suitable for this, since the value of the semaphore would have to be accessed unsynchronized. In principle, it would be possible to use shared memory, nonblocking pipes or messages. Since here an unknown number of processes can communicate with each other a solution with Shared Memory would be probably a good choice, since one must know here neither source nor destination and besides all at the same time bidirectional access have. However, access should also be secured with a mutex for this very reason.

Here are a few sources in the Windows context:
https://learn.microsoft.com/en-us/windows/win32/memory/sharing-files-and-memory
https://learn.microsoft.com/en-us/windows/win32/ipc/synchronous-and-overlapped-input-and-output
https://learn.microsoft.com/en-us/windows/win32/ipc/reading-from-a-mailslot

Example: Creating Named Shared Memory (Windows):
https://learn.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory

The C++ source code for Windows might look like this at the beginning:
C++
HANDLE hMutexApp = CreateMutex( NULL, FALSE, TEXT("MyMutexApp"));
HANDLE hMutexShm = CreateMutex( NULL, FALSE, TEXT("MyMutexShm"));

HANDLE hMapFile;
const DWORD BUF_SIZE = 256;
TCHAR szName[] = TEXT("Global\\MyFileMappingObject");

hMapFile = CreateFileMapping(
	INVALID_HANDLE_VALUE,    // use paging file
	NULL,                    // default security
	PAGE_READWRITE,          // read/write access
	0,                       // maximum object size (high-order DWORD)
	BUF_SIZE,                // maximum object size (low-order DWORD)
	szName);                 // name of mapping object

// map object to pointer
LPCTSTR pBuf = (LPTSTR)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE);


Alternatively, a solution with threading and only semaphores would probably be possible here. The whole thing works similarly under Linux, only that the system calls differ.
 
Share this answer
 
v2
Comments
CoadyCoder 22-Jan-23 6:58am    
Thank you but I'm struggling with the coding part actually
merano99 22-Jan-23 7:52am    
As I said before, cross-process synchronization is not (easily) possible with pure C++. Since neither the operating system nor the compiler are known, several variants would have to be discussed here. It would be good if you could narrow down the framework.
Richard MacCutchan 22-Jan-23 11:46am    
Look at Andre Oosthuizen's update, he has provided all the code that you need.
merano99 22-Jan-23 15:28pm    
He didn't address the aspect that the application should be able to continuously output during execution and also receive on commands, did he?
Richard MacCutchan 23-Jan-23 4:37am    
The OP is expected to do at least some of the work.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900