counting number of files in a Dir , switching btwn functions

Jan 2, 2017 at 9:37am
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 Jan 2, 2017 at 2:18pm
Jan 2, 2017 at 10:44am
closed account (SECMoG1T)
Hello anyone or maybe some advice
Jan 2, 2017 at 1:36pm
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?
Jan 2, 2017 at 2:01pm
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 Jan 2, 2017 at 2:28pm
Jan 2, 2017 at 4:26pm
closed account (SECMoG1T)
Hello people any advice/help ?
Jan 2, 2017 at 5:29pm
> 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.
Jan 2, 2017 at 7:19pm
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.
Jan 3, 2017 at 1:16am
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).
Jan 3, 2017 at 8:15am
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 Jan 3, 2017 at 9:06am
Jan 4, 2017 at 2:45am
> 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
Jan 9, 2017 at 9:41am
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.