counting number of files in a Dir , switching btwn functions

closed account (SECMoG1T)
Hello everyone, I have a console program that I created, it works fine but I would use some help to solve two puzzles that I seem to be facing.

Basically my code looks like this..
1
2
3
4
5
6
  void MainHandler
     {
        Initialize(/*some flags here*/);/// this are my basic function but my real program uses a switch
        Update();                                     /// to call them based on my selection. 
        Review();
     }


Nb: any of the three functions can run for a really long time that's why I would like to have a way of interrupting them, i also have no idea on windows programming if that helps.

Q1. my update function basically runs if I have added new files to the default directory but I usually do this update manually and mainly by restarting my app and selecting the update function, I would really love to have another function that will run auto when update is called check if I have added new files , if so the update continues else it returns.

Note that all file have the same extension .dtx

Q2.my initialize function loads data from files into a primitive database and then it proceeds to a processing stage which can usually take sometime
I would love to have a function like listener(char&) such that if I press 'u' on my keyboard during the processing stage, my program would call the update function instantly , if I do the same with 'r' it would call the review function. ...


IS THIS POSSIBLE...

Any help will be greatlly appreciated,
Cheers Andy.
Last edited on
closed account (SECMoG1T)
Hello anyone or maybe some advice
What do you need help with?

a. How to run a function (which has a can callback) asynchronously?
or
b. How to periodically check if new files have been added to a particular directory?
closed account (SECMoG1T)
Thank you for the reply... well am not very sure what (a) means but my aim is to be able to interrupt a function using key presss for example. ..

1) after starting my app ..my intitialize function is called and then it proceeds to data processing .... during this period I might want to review some data that is already processed.

2) by pressing 'r' on my keyboard I would like to save the current processing which isn't a problem and then instantly switch to the review function.

3) my easiest thought was to have a function listener() maybe on a different thread and then send the current key pressed to my other thread (not very sure )

My idea is to switch between different functions without having to restart my app which is what am currently doing.

your (b) is exactly what I want to achieve next.
Last edited on
closed account (SECMoG1T)
Hello people any advice/help ?
> my easiest thought was to have a function listener() maybe on a different thread
> and then send the current key pressed to my other thread

Perhaps have a listener thread add keyboard input to a producer-consumer queue, and use a condition variable to notify the main thread that keyboard input has arrived.
https://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html


> (b) is exactly what I want to achieve next

std::experimental::filesystem could be used for this.

There is a very basic example here: http://www.cplusplus.com/forum/general/205602/#msg973593

You would want to store the last write time in addition to the fil;e name
http://en.cppreference.com/w/cpp/experimental/fs/last_write_time

And then a diff between the earlier list of files and the current list of files would yield the list of files that have been added / modified.
closed account (SECMoG1T)
Ooh yea , now this seems like what I am looking for.... i'll be checking your references right away...
Btw a quick question .... how would you suggest I implement the function to read keyboard input , should I use the normal std::streams objects (std::cin) or do I reqire a more specialized function?

Ill update as I implement and in case of any other querries .

Thank you very much,
Andy.
std::cin.get http://en.cppreference.com/w/cpp/io/basic_istream/get
can be used to read a character; but the call would block if there is no input as yet
(the input would typically become available only after the user presses the enter key).
closed account (SECMoG1T)
If I spawn tha listener thread just to handle the input incase I hit any letter , what happens if the call to get () blocks ?

Is there anyway to do non blocking io? Anyway I'll be ... trying

Update: i successfly did your (b) , almost done but I found out I dint have <experimental/filesystem.hpp>
Luckly i got boost.
Last edited on
> If I spawn tha listener thread just to handle the input incase I hit any letter ,
> what happens if the call to get () blocks ?

The listener thread would block, but that shouldn't matter as the main thread will continue to execute.

For instance:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
#include <functional>
#include <atomic>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <future>
#include <chrono>


namespace listener
{
    std::mutex mutex ;
    std::condition_variable condition_variable ;
    std::queue<char> input_queue ;

    void listen()
    {
        char c ;
        while( std::cin >> c ) // blocks for character input
        {
            std::unique_lock<std::mutex> lock(mutex) ;
            input_queue.push(c) ;
            lock.unlock() ;
            condition_variable.notify_one() ;
        }
    }
}

int main()
{
    using namespace std::chrono_literals;

    const auto process_input = [] ( char c )
    {
        std::cout << "\n*** process input '" << c << "' ***\n\n" << std::flush ;
        std::this_thread::sleep_for( 100ms ) ; // simulate processing input
    };

    const auto do_something_else = []
    {
        std::cout << "continue doing something else\n" << std::flush ;
        std::this_thread::sleep_for( 800ms ) ; // simulate doing something else
    };

    std::cout << "enter characters to be processed, eof (ctrl-D/ctrl-Z) to quit\n\n" ;
    auto future = std::async( std::launch::async, listener::listen ) ;

    while(std::cin)
    {
        static const auto input_available = [] { return !listener::input_queue.empty() ; } ;

        std::unique_lock<std::mutex> lock(listener::mutex) ;

        // http://en.cppreference.com/w/cpp/thread/condition_variable/wait_for
        // this blocks for a maximum of 10 milliseconds
        if( listener::condition_variable.wait_for( lock, 10ms, input_available ) )
        {
            char c = listener::input_queue.front() ;
            listener::input_queue.pop() ;
            lock.unlock() ;
            process_input(c) ;
        }
        else do_something_else() ;
    }
}


> Is there anyway to do non blocking io?

We would need to use platform-specific features for non-blocking input from stdin.
For portable code, use a library that wraps the platform specific stuff;
for instance curses with nodelay() or halfdelay()
http://man7.org/linux/man-pages/man3/curs_inopts.3x.html
closed account (SECMoG1T)
Ooh thanks man, hadn't been around, thank you for that guide i'll be lookin into it now that i got sometime to.

what do you think of my class implementing your solution to my second problem.

http://pastebin.com/HRWmZtUJ
Topic archived. No new replies allowed.