Utilisation of multi-threading while reading a file and want to find the top 20 most frequently used words
Code Review

A lot of people like to put some logical order on the includes.

#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;set&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;map&gt;
#include &lt;mutex&gt;
#include &lt;fstream&gt;


I like to put containers together, streams stuff together, C stuff together; others like to order them alphabetically. But with this many includes some sort of logic is probably a good idea.

You don't need to use this old library.

#include &lt;pthread.h&gt;


Threading is now part of the C++ standard. All the threading and mutex classes are included.

Not sure what these are:

#include "mingw-std-threads-master/mingw-std-threads-master/mingw.thread.h"
#include "mingw-std-threads-master/mingw-std-threads-master/mingw.mutex.h"


But that seems awfully deeply nested. Which usually means that there are are top level includes that include these files indirectly. A comment with a link to the documentation would be nice especially since a maintainer is not likely to know about these.

Hmmm

//bad practise but convenient for this code example
using namespace std;


C Macro

No need to use macros. There are better C++ alternatives.

//File to read so that we can find the most frequent used words.
#define FILENAME "mobydick.txt"

//The amount of words to find which are most used.
#define WORDS_TO_FIND 20


Notice we can type these correctly now.

// http://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
static std::string constexpr fileName    = "mobydick.txt"s;
static int constexpr         wordsToFind = 20;


Globals

Globals is a bad idea. These should be wrapped in a class object.

map&lt;string,int&gt; word_count;
queue&lt;string&gt; word_queue;
std::mutex m;                // inconsistent use of std::

//Not great approach but condition_variable is not available in my environment.
bool keep_running = true;


Locals

Love it.
Not enough people work out how to use the streams and locals correctly.

//Ignore punctuations coming from the stream, and to read only valid "english" letters from the input stream.
//This is an improvement but it still doesn't cover all cases.
struct letter_only: ctype&lt;char&gt;
{
    letter_only(): ctype&lt;char&gt;(get_table()) {}

    static ctype_base::mask const* get_table()
    {
        static vector&lt;ctype_base::mask&gt; rc(ctype&lt;char&gt;::table_size,ctype_base::space);

        fill(&amp;rc['a'], &amp;rc['z'+1], ctype_base::alpha);
        return &amp;rc[0];
    }
};


Insert

Your lock is over too large a surface area. You lock the queue even while you are working on word_count and this is not used by the reader thread. The reader thread could be actively using the queue while you play with the word count object.

You should also look into using RAII to correctly lock and unlock your lock.

You read loop is a busy loop. You are going to melt the processor doing this. It would be better to use a condition variable and force the thread to sleep if the queue is empty (which it will be most of the time).

Lastly you overcomplicated the addition.

std::string getWord()
{
    std::lock_guard&lt;std::mutex&gt;  lock(m);   // Only lock as long as you need.
    std::word result = word_queue.front();
    word_queue.pop();
    return result;
}
void insert()
{
    string word;

    while(keep_running || (!keep_running &amp;&amp; !word_queue.empty()))
    {
        // Add condition variable here.
        if(!word_queue.empty())
        {
            // Call getWord() that locks as part of the access
            // It is in a separate function so that the RAII lock
            // can simply unlock on exit.
            word = getWord();

            // If word does not exist. The [] operator inserts a value
            // using `word` as the key and zero-initializes the value 
            // so for an int the value inserted is a zero.
            // 
            // It returns a reference to the value, so you can simply
            // increment the result of the operation.
            ++word_count[word];
       }
    }
}


Optimization

This is very expensive.    

    for(int i = 0; i &lt; WORDS_TO_FIND; i++)
    {
        for(auto it = word_count.begin(); it != word_count.end(); ++it )
        {


You are basically looping over all the words 20 times. This list could be huge. There are 171,476 words in the english language (assume no spelling mistakes many more if you include these). You can replace this and loop over the words once and just keep track of the top 20.