Semaphore in shared memory with Python on Windows? -


here's scenario. have python script launch program (let's call p) before running main code. multiple python scripts can ran @ same time, if program p has been started, should not started again:

pid 100 starts pid 100 starts program p pid n , detaches pid 100 runs main pid 101 starts pid 101 not start program p because it's started pid 101 runs main pid 100 main finishes pid 100 not terminate program p because pid 101 needs pid 100 terminates pid 101 main finishes pid 101 terminates program p pid n pid 101 terminates 

in c can create shared memory mmaping file , putting semaphore in track that. once semaphore reaches 0 can terminate program p. have no idea how in python and on windows.

how should approach problem, i.e. there established method of solving this?

i've created example of how can achieve behavior on windows using sockets rather shared memory semaphore. achieves same thing; c++ program keep running long @ least 1 of python scripts running. once scripts have finished, c++ program finish long no more python scripts started within timeout period.

most of code here goes c++ program, runs thread monitors tcp connections python script(s).

the python script checks/starts windows program, opens socket left open until script ends.

the windows program detects socket connections , disconnections, keeping track of when python scripts running.

in these examples, windows program happens called "consoleapplication11.exe". i've used port 1234 , timeout of 15 seconds, can change these in lines 19-21 of c++ program. also, if want make termination of c++ program more immediate, call exit() instead of return @ end of client_monitor_thread().

hope may useful.

python script:

import socket import time import psutil import os  # check if c++ program running, start if not cppprogramname = "consoleapplication11.exe" progrunning = false pid in psutil.pids():     p = psutil.process(pid)     if (cppprogramname in p.name()):         progrunning = true  if not progrunning:     os.startfile(cppprogramname)     time.sleep(5) # wait c++ program start  # open socket c++ program tell need keep running s = socket.socket(socket.af_inet, socket.sock_stream) s.connect(("127.0.0.1", 1234))  # (main program) time.sleep(3) # (end of main program)  # close socket c++ program s.close() 

c++ program:

// consoleapplication11.cpp : defines entry point console application. //  #include "stdafx.h"  #include <iostream> #include <set> #include <chrono> #include <thread>  #include <winsock2.h> #include <ws2tcpip.h>  #pragma comment(lib, "ws2_32.lib")              // link ws2_32.lib   namespace {     const unsigned int commonport            = 1234;   // must match python app     const unsigned int noclientstimeoutlimit = 15;     // quit when no clients connected many seconds     bool               clientmonitorrunning  = true;   // flag show client monitor running       void client_monitor_thread()     {         // start winsock service version 2.2         wsadata wsadata;         int iresult = wsastartup(makeword(2, 2), &wsadata);         if (iresult != no_error)         {             std::cout << "wsastartup() failed error: " << iresult << std::endl;             clientmonitorrunning = false;             return;         }          // create socket listening incoming connection requests.         socket listensocket = socket(af_inet, sock_stream, ipproto_tcp);         if (listensocket == invalid_socket)         {             std::cout << "socket() function failed error: " << wsagetlasterror() << std::endl;             closesocket(listensocket);             clientmonitorrunning = false;             return;         }          // sockaddr_in structure specifies address family, ip address, , port socket          sockaddr_in service;         service.sin_family = af_inet;         inet_pton(af_inet, (pcstr)"127.0.0.1", &(service.sin_addr));         service.sin_port = htons(commonport);         if (socket_error == bind(listensocket, (sockaddr *)& service, sizeof(service)))         {             std::cout << "bind function failed error " << wsagetlasterror() << std::endl;             closesocket(listensocket);             clientmonitorrunning = false;             return;         }          // listen incoming connection requests on created socket         if (socket_error == listen(listensocket, somaxconn))         {             wprintf(l"listen function failed error: %d\n", wsagetlasterror());             closesocket(listensocket);             clientmonitorrunning = false;             return;         }          std::cout << "listening on port " << commonport << std::endl;          // mow monitor client connections         std::set<unsigned int> activefds;         int timeoutcounter = 0;          while (clientmonitorrunning)         {             // check existing clients disconnected             if (0 != activefds.size())             {                 std::set<unsigned int> disconnectedfds;                 (auto fd : activefds)                 {                     int flags = 0;                     char buf[10];                     int rv = recv(fd, buf, 10, flags);                     if (0 == rv)                     {                         disconnectedfds.insert(fd);                     }                 }                 (auto fd : disconnectedfds)                 {                     activefds.erase(fd);                 }             }              // clients connected? need quit?             if (0 == activefds.size())             {                 std::cout << "no clients - exit in " << noclientstimeoutlimit - timeoutcounter << " seconds" << std::endl;                 ++timeoutcounter;                 if (timeoutcounter == noclientstimeoutlimit)                 {                     (auto fd : activefds)                     {                         closesocket(fd);                     }                     closesocket(listensocket);                     clientmonitorrunning = false;                     return;                 }             }             else             {                 timeoutcounter = 0;             }              // check activity on listening socket             fd_set readfds;             struct timeval timeout;             timeout.tv_sec = 1;             timeout.tv_usec = 0;             fd_zero(&readfds);             fd_set(listensocket, &readfds);             switch (select(sizeof(readfds), &readfds, null, null, &timeout))             {             case 0: // timeout             {                 break;             }             case socket_error:             {                 std::cout << "listen failed error: " << wsagetlasterror() << std::endl;                 closesocket(listensocket);                 clientmonitorrunning = false;                 return;             }             default:             {                 if (fd_isset(listensocket, &readfds))                 {                     // accept connection.                     socket fd = accept(listensocket, null, null);                     if (fd == invalid_socket)                     {                         std::cout << "accept failed error: " << wsagetlasterror() << std::endl;                         closesocket(listensocket);                         clientmonitorrunning = false;                         return;                     }                     else                     {                         unsigned long nonblock = 1;                         ioctlsocket(fd, fionbio, &nonblock);                         activefds.insert(fd);                     }                 }                 break;             }             }         }          return;     } }   int main() {     // start client monitor thread, run until no clients connected     std::thread clientmonitor(client_monitor_thread);      // placeholder doing actual work in program     // loop until client monitor thread exits     while (clientmonitorrunning)     {         std::this_thread::sleep_for(std::chrono::seconds(1));     }      // clean     clientmonitor.join();     wsacleanup();     return 0; } 

Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -