Creating global named counter shared between processes - c++

How can I create a global counter-value that can be shared between multiple processes in c++? What I need is a way to "invalidate" multiple processes at once, signaling them to perform some operation (like reading from file). All processes would continuously poll (every 10ms) for current counter-value and compare it with internally stored last value. Mismatching values would indicate that some work is needed.
Edit: btw my processes are executing as different .exe:s, not created from some parent process. Operating system is windows.

What about a named semaphore? Posix supports it, not sure about windows.

Consider the way you want to distribute the information and potential overlaps - if it takes longer for any of the readers to finish reading than it takes for a refresh then you are going to get in trouble with the suggested approach.
The way I read your question, there are multiple readers, the writer doesn't know (or care in most part) how many readers there are at one time, but wants to notify the readers that something new is available to read.
Without knowing how many potential readers there are you can't use a simple mutex or semaphore to know when the readers are done, without knowing when everybody is done you don't have good info on when to reset an event to notify for the next read event.
MS Windows specific:
Shared Segments
One option is to place variables within a shared data segment. That means that the same variables can be read (and written to) by all exe's that have named the same segment or if you put it into a DLL - loaded the shared DLL.
See http://www.codeproject.com/KB/DLL/data_seg_share.aspx for more info.
// Note: Be very wary of using anything other than primitive types here!
#pragma data_seg(".mysegmentname")
HWND hWnd = NULL;
LONG nVersion = -1;
#pragma data_seg()
#pragma comment(linker, "/section:.mysegmentname,rws")
IPC - COM
Make your main app a com service where the workers can register with for events, push out the change to each event sink.
IPC - dual events
Assuming any 1 read cycle is much less than time between write events.
create 2 manual reset events, at any time at most 1 of those events will be signaled, alternate between events. signaling will immediatly release all the readers and once complete they will wait on the alternate event.

you can do this the easy way or the way
the easy way is to store shared values in registry or a file so that all processes agree to check it frequently.
the hard way is to use IPC(inter process communication, the most common method that i use is NamedPipes. its not too hard because you can find plenty of resources about IPC on the net.

If you are on *nix you could make the processes read from a named pipe (or sockets), and then write the specific msg there to tell the other processes that they should shutdown.
IPC performance: Named Pipe vs Socket
Windows NAmed Pipes alternative in Linux

Use a named event object with manual reset. The following solution doesn't use the CPU so much than busy waiting
Sending process:
Set event
Sleep 10 ms
Reset Event
Receiving processes:
All waiting processes pass when event is set
They read the file
Let them sleep for 20 ms, so say can't see the same event twice.
Wait again
Sleep( 10 ) might actually take longer than Sleep( 20 ) but this only results in another cycle (reading the unchanged file again).

As the name of the executable is known, I have another solution which I implemented (in C#) in a project just a few days ago:
Every reader process creates a named event "Global\someuniquestring_%u" with %u being it's process id. If the event is signaled, read the file and do the work.
The sender process has a list of event handles and sets them active if the file has changed and thus notifys all reader processes. From time to time, e.g. when the file has changed, it has to update the list of event handles:
Get all processes with name 'reader.exe' (e.g.)
For every process get it's id
Open a handle for the existing event "Global\someuniquestring_%u" if it's a new process.
Close all handles for no longer running processes.

Found one solution for monitoring folder changes (with "event_trigger"-event) and reading additional event information from file:
HANDLE event_trigger;
__int64 event_last_time;
vector<string> event_info_args;
string event_info_file = "event_info.ini";
// On init
event_trigger = FindFirstChangeNotification(".", false, FILE_NOTIFY_CHANGE_LAST_WRITE);
event_last_time = stat_mtime_force("event_info.ini");
// On tick
if (WaitForSingleObject(event_trigger, 0)==0)
{
ResetEventTrigger(event_trigger);
if (stat_mtime_changed("event_info.ini", event_last_time))
{
FILE* file = fopen_force("event_info.ini");
char buf[4096];
assert(fgets(buf, sizeof(buf), file));
split(buf, event_info_args, "\t\r\n");
fclose(file);
// Process event_info_args here...
HWND wnd = ...;
InvalidateRect(wnd,0,false);
}
}
// On event invokation
FILE* file = fopen("event_info.ini", "wt");
assert(file);
fprintf(file,"%s\t%s\t%d\n",
"par1", "par2", 1234);
fclose(file);
stat_mtime_changed("event_info.ini", event_last_time);
// Helper functions:
void ResetEventTrigger()
{
do
{
FindNextChangeNotification(evt);
}
while(WaitForSingleObject(evt, 0)==0);
}
FILE* fopen_force(const char* file);
{
FILE* f = fopen(file, "rt");
while(!f)
{
Sleep(10+(rand()%100));
f = fopen(f, "rt");
}
assert(f);
return f;
}
__int64 stat_mtime_force(const char* file)
{
struct stat stats;
int res = stat(file, &stats);
if(res!=0)
{
FILE* f = fopen(file, "wt");
fclose(f);
res = stat(file, &stats);
}
assert(res==0);
return stats.st_mtime;
}
bool stat_mtime_changed(const char* file, __int64& time);
{
__int64 newTime = stat_mtime(file);
if (newTime - time > 0)
{
time = newTime;
return true;
}
return false;
}

Related

Can two different processes communicate with each other using Windows events in WINAPI?

I am in the midst of developing two applications that communicate using a file. These applications are running on the same machine. To be clear, I have a writer.exe and a reader.exe executables.
The writer.exe constantly writes a random integer to a common file "some_file.bin" and closes the file. It repeats the same process again: opens the file, writes random int and closes it. This is done in a while loop.
The reader.exe is constantly reading the file "some_file.bin", printing the read integer to its console.
Both of these applications are written in C++ using the std::fstream class for file I/O.
So far, this is not working properly, because we have a race condition happening here.
I want some way to properly communicate between these two processes, using Win32 Events, so that the writer.exe process knows to wait until the reader.exe process has finished reading, and the reader.exe process knows to pause until the writer.exe process has finished writing.
I'm hoping to do this using the CreateEvent, WaitForSingleObject family of API calls present natively on the Windows platform.
Please feel free to tell me if this is possible between two processes?
So far, I have only found examples using the above APIs to signal threads of one main process... ?
Yes, it is possible. When one process creates a handle to an Event object, you have the option of assigning a name to that object in the kernel. The other process can then create/open its own handle to that Event object using the same name.
Note that to accomplish what you want, you actually would need 2 Events, eg:
writer.exe:
HANDLE hReadable = CreateEvent(NULL, FALSE, FALSE, TEXT("ReaderCanRead"));
if (!hReadable) ...
HANDLE hWritable = CreateEvent(NULL, FALSE, TRUE, TEXT("WriterCanWrite"));
if (!hWritable) ...
...
while (!quit)
{
...
WaitForSingleObject(hWritable, INFINITE);
if (quit) break;
// write int...
SetEvent(hReadable);
...
}
reader.exe:
HANDLE hReadable = CreateEvent(NULL, FALSE, FALSE, TEXT("ReaderCanRead"));
// or: HANDLE hReadable = OpenEvent(SYNCHRONIZE, FALSE, TEXT("ReaderCanRead"));
if (!hReadable) ...
HANDLE hWritable = CreateEvent(NULL, FALSE, TRUE, TEXT("WriterCanWrite"));
// or: HANDLE hWritable = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("WriterCanWrite"));
if (!hWritable) ...
...
while (!quit)
{
...
WaitForSingleObject(hReadable, INFINITE);
if (quit) break;
// read int...
SetEvent(hWritable);
...
}
That being said, you might consider using a named block of shared memory via CreateFileMapping()+MapViewOfFile(), rather than using a physical file.
However, there are many other Inter-Process Communication mechanisms that are way more suitable to your producer/consumer model than using a shared file/memory protected by Events. Pipes, sockets, mailslots, even window messages, would be a much better choice.

Cancel blocking `poll`?

So, I've run into this issue where I have many threads calling poll on different file descriptors. When I want to add a new one, I need to cancel one of those polls, add a new one, and continue. That alone sounds bad, but also I can't even see how to do that.
Some relevant code:
struct pollfd fds[size];
for(int i = 0;i<size;i++) {
struct pollfd fd;
fd.fd = body[i];
fd.events = POLLIN;
fd.revents = 0;
fds[i] = fd;
}
if(poll(&fds[0], (nfds_t)size, -1) < 0) return NULL;
(I'm using this through JNI also).
I figure I could set a really low delay on poll, and call it over and over, but I think that would begin to defeat the purpose.
The way you can do it is: open a socket or a pipe where, when there is a new file descriptor to add to a polling set, another thread sends some data. Thus, poll will return, you check this reserved file descriptor. If there is data, it means there is a new file descriptor to add.
You can send your process a signal, causing poll() to return -1 and set errno to EINTR. The signal should obviously not cause the process to terminate, so you may need to get some sigaction() or sigprocmask(). However, any signal received between calling either of those and poll() may get lost, similar to select()/pselect(). For this reason some systems may provide additional, non-standard replacements for poll(), like ppoll(), which include a sigset_t to change the signal disposition atomically.

Interogate which process has locked a file in Windows C ++

I have 2 applications sharing the same lock file, and I need to know when the
the other application has either locked/unlocked the file. The code below was
originally implemented on a Linux machine, and is being ported to Window 8, VS12.
I have ported all other code in the class successfully and am locking files with
LockFile(handle, 0, 0, sizeof(int), 0) and the equivalent UnlockFile(...). However,
I am having trouble with the following wait() command.
bool devices::comms::CDeviceFileLock::wait(bool locked,
int timeout)
{
// Retrieve the current pid of the process.
pid_t pid = getpid();
// Determine if we are tracking time.
bool tracking = (timeout > 0);
// Retrieve the lock information.
struct flock lock;
if (fcntl(m_iLockFile, F_GETLK, &lock) != 0)
raiseException("Failed to retrieve lock file information");
// Loop until the state changes.
time_t timeNow = time(NULL);
while ((pid == lock.l_pid)
&&
(lock.l_type != (locked ? F_WRLCK : F_UNLCK)))
{
// Retrieve the lock information.
if (fcntl(m_iLockFile, F_GETLK, &lock) != 0)
raiseException("Failed to retrieve lock file information");
// Check for timeout, if we are tracking.
if (tracking)
{
time_t timeCheck = time(NULL);
if (difftime(timeNow, timeCheck) > timeout)
return false;
}
}
// Return success.
return true;
}
Note: m_iLockFile used to be a file descriptor from open(), it is now called
m_hLockFile and is a HANDLE from CreateFile().
I cannot seem to find the Windows equivalent of the fcntl F_GETLK command.
Does anyone know if I can either:
a) use an fcntl equivalent to interrogate locking information, to find out
which process has obtained the lock
b) suggest how the above can be re-written for Windows C++.
Note: The server application using the lock file is a standalone C++ executable,
however the client using the lock file is a WinRT Windows Application. So any
suggested solution cannot break the sandboxing of the client.
Thanks.
You are not going to find this in Windows, it is fundamentally unsound on a multi-tasking operating system. The value you'd get from an IsFileLocked() api function is meaningless, another process or thread could still lock the file a microsecond later.
The workaround is simple, if you need to lock then just try to acquire one. If the file is already locked then LockFile() will simply return FALSE, GetLastError() tells you why. Now it is atomic, an essential property of a lock. If you can afford to wait for the lock then use LockFileEx() without the LOCKFILE_FAIL_IMMEDIATELY option.
I am just googling for you, but I found this
"Various C language run-time systems use the IOCTLs for purposes
unrelated to Windows Sockets. As a consequence, the ioctlsocket
function and the WSAIoctl function were defined to handle socket
functions that were performed by IOCTL and fcntl in the Berkeley
Software Distribution."
There is also a brief discussion here - it is python based but has some clues.

Reliable way to count running instances of a process on Windows using c++/WinAPIs

I need to know how many instances of my process are running on a local Windows system. I need to be able to do it using C++/MFC/WinAPIs. So what is a reliable method to do this?
I was thinking to use process IDs for that, stored as a list in a shared memory array that can be accessed by the process. But the question is, when a process is closed or crashes how soon will its process ID be reused?
The process and thread identifiers may be reused any time after closure of all handles. See When does a process ID become available for reuse? for more information on this.
However if you are going to store a pair of { identifier, process start time } you can resolve these ambiguities and detect identifier reuse. You can create a named file mapping to share information between the processes, and use IPC to synchronize access to this shared data.
You can snag the process handles by the name of the process using the method described in this question. It's called Process Walking. That'll be more reliable than process id's or file paths.
A variation of this answer is what you're looking for. Just loop through the processes with Process32Next, and look for processes with the same name using MatchProcessName. Unlike the example in the link I provided, you'll be looking to count or create a list of the processes with the same name, but that's a trivial addition.
If you are trying to limit the number of instances of your process to some number you can use a Semaphore.
You can read in detail here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686946(v=vs.85).aspx
In a nutshell, the semaphore is initialized with a current count and max count. Each instance of your process will decrement the count when it acquires the semaphore. When the nth process tries to acquire it but the count has reached zero that process will fail to acquire it and can terminate or take appropriate action.
The following code should give you the gist of what you have to do:
#include <windows.h>
#include <stdio.h>
// maximum number of instances of your process
#define MAX_INSTANCES 10
// name shared by all your processes. See http://msdn.microsoft.com/en-us/library/windows/desktop/aa382954(v=vs.85).aspx
#define SEMAPHORE_NAME "Global\MyProcess"
// access rights for semaphore, see http://msdn.microsoft.com/en-us/library/windows/desktop/ms686670(v=vs.85).aspx
#define MY_SEMAPHORE_ACCESS SEMAPHORE_ALL_ACCESS
DWORD WINAPI ThreadProc( LPVOID );
int main( void )
{
HANDLE semaphore;
// Create a semaphore with initial and max counts of MAX_SEM_COUNT
semaphore = CreateSemaphore(
NULL, // default security attributes
MAX_INSTANCES, // initial count
MAX_INSTANCES, // maximum count
SEMAPHORE_NAME );
if (semaphore == NULL)
{
semaphore = OpenSemaphore(
MY_SEMAPHORE_ACCESS,
FALSE, // don't inherit the handle for child processes
SEMAPHORE_NAME );
if (semaphore == NULL)
{
printf("Error creating/opening semaphore: %d\n", GetLastError());
return 1;
}
}
// acquire semaphore and decrement count
DWORD acquireResult = 0;
acquireResult = WaitForSingleObject(
semaphore,
0L); // timeout after 0 seconds trying to acquire
if(acquireResult == WAIT_TIMEOUT)
{
printf("Too many processes have the semaphore. Exiting.");
CloseHandle(semaphore);
return 1;
}
// do your application's business here
// now that you're done release the semaphore
LONG prevCount = 0;
BOOL releaseResult = ReleaseSemaphore(
semaphore,
1, // increment count by 1
&prevCount );
if(!releaseResult)
{
printf("Error releasing semaphore");
CloseHandle(semaphore);
return 1;
}
printf("Semaphore released, prev count is %d", prevCount);
CloseHandle(semaphore);
return 0;
}
Well, your solution is not very reliable. PIDs can be reused by the OS at any later time.
I did it once by going through all the processes and comparing their command line string (the path of the executable) with the one for my process. Works pretty well.
Extra care should be taken for programs that are started via batch files (like some java apps/servers).
Other solutions involve IPC, maybe through named pipes, sockets, shared memory (as you mentioned). But none of them are that easy to implement and maintain.

child waiting for another child

is there a way for a forked child to examine another forked child so that, if the other forked child takes more time than usual to perform its chores, the first child may perform predefined steps?
if so, sample code will be greatly appreciated.
Yes. Simply fork the process to be watched, from the process to watch it.
if (fork() == 0) {
// we are the watcher
pid_t watchee_pid = fork();
if (watchee_pid != 0) {
// wait and/or handle timeout
int status;
waitpid(watchee_pid, &status, WNOHANG);
} else {
// we're being watched. do stuff
}
} else {
// original process
}
To emphasise: There are 3 processes. The original, the watcher process (that handles timeout etc.) and the actual watched process.
To do this, you'll need to use some form of IPC, and named shared memory segments makes perfect sense here. Your first child could read a value in a named segment which the other child will set once it has completed it's work. Your first child could set a time out and once that time out expires, check for the value - if the value is not set, then do what you need to do.
The code can vary greatly depending on C or C++, you need to select which. If C++, you can use boost::interprocess for this - which has lots of examples of shared memory usage. If C, then you'll have to put this together using native calls for your OS - again this should be fairly straightforward - start at shmget()
This is some orientative code that could help you to solve the problem in a Linux environment.
pid_t pid = fork();
if (pid == -1) {
printf("fork: %s", strerror(errno));
exit(1);
} else if (pid > 0) {
/* parent process */
int i = 0;
int secs = 60; /* 60 secs for the process to finish */
while(1) {
/* check if process with pid exists */
if (exist(pid) && i > secs) {
/* do something accordingly */
}
sleep(1);
i++;
}
} else {
/* child process */
/* child logic here */
exit(0);
}
... those 60 seconds are not very strict. you could better use a timer if you want more strict timing measurement. But if your system doesn't need critical real time processing should be just fine like this.
exist(pid) refers to a function that you should have code that looks into proc/pid where pid is the process id of the child process.
Optionally, you can implement the function exist(pid) using other libraries designed to extract information from the /proc directory like procps
The only processes you can wait on are your own direct child processes - not siblings, not your parent, not grandchildren, etc. Depending on your program's needs, Matt's solution may work for you. If not, here are some other alternatives:
Forget about waiting and use another form of IPC. For robustness, it needs to be something where unexpected termination of the process you're waiting on results in your receiving an event. The best one I can think of is opening a pipe which both processes share, and giving the writing end of the pipe to the process you want to wait for (make sure no other processes keep the writing end open!). When the process holding the writing end terminates, it will be closed, and the reading end will then indicate EOF (read will block on it until the writing end is closed, then return a zero-length read).
Forget about IPC and use threads. One advantage of threads is that the atomicity of a "process" is preserved. It's impossible for individual threads to be killed or otherwise terminate outside of the control of your program, so you don't have to worry about race conditions with process ids and shared resource allocation in the system-global namespace (IPC objects, filenames, sockets, etc.). All synchronization primitives exist purely within your process's address space.