I am required to process many shopping carts in front of many queues using multithreading. I created a container for database from a given file holds strings barocdes, item name, and price. Also created a container for customer carts from given file that holds strigns cart number and barcode of items. The requirement is to lock the process when scanning a single item only NOT the whole items of a cart to let other queues process their cart then printing the receipts. I put mutex lock before and after scanning statement but failed to store each cart items separated on other carts. I set everything well but the process function I have an issue with, becasue the receipts I got has a mess or truncated. I am new with multithreading concepts and spent long time with is code but I stuck and I need an advise of what is wrong on my function. Thanks in advance.
#include <fstream>
#include <cstdlib>
#include <string>
#include <iostream>
#include <vector>
#include <regex>
#include <algorithm>
#include <tuple>
#include <bitset>
#include <math.h>
#include <sstream>
#include <unordered_map>
#include <condition_variable>
#include <thread>
#include <mutex>
#include <queue>
#include <iomanip>
using namespace std;
std::mutex dataBaseMut;
//********************************************
class cartManager
{
//this function parametes are database and SINGLE queue
void processCarts(const unordered_map<string, pair<string, string>>&
dataBase
, queue<pair<string, vector<string>>>& singleQue)
{
// deque to hold cartNo, itemName, and price
string totalPrice = "";
string cartNo;
string cartItem;
string itemPrice;
string barcode;
bool errorFlag = false;;
//if signle queue is not empty, then process the carts
while (!singleQue.empty())
{
int frontCartSize;
//detemine the queue size
int singleQueSzie = singleQue.size();
//get cartNo of cart that is in front of deque
cartNo = singleQue.front().first;
int j = 0;
//get cartSize of cart that is in front of deque
frontCartSize = singleQue.front().second.size();
// process in front cart items till end of items
for (; j < frontCartSize; j++)
{
string notfound = " ";
stringstream items;
dataBaseMut.lock();
// search barode of an item in data base
auto it = dataBase.find(singleQue.front().second[j]);
//if not found then search it in errorlog
if (it == dataBase.end())
{
for (int i = 0; i < errorLogProducts.size(); i++)
{
if (errorLogProducts[i] == singleQue.front().second[j])
{
string cartItem = singleQue.front().second[j];
errorFlag = true;
}
}
}
else // if found,then get info of the item from data base
{
cartNo = singleQue.front().first; // get cart number
cartItem = it->second.first; // get item name
itemPrice = it->second.second; //get item price
//push all above into a vector
cartNo_Item_Price.push_back(make_tuple(cartNo,
make_pair(cartItem, itemPrice)));
}
dataBaseMut.unlock();
//if you reach the end of items of a cart, then remove it from deque
if (j == singleQue.front().second.size() - 1)
{
singleQue.pop(); // remove processed cart
}
}
}
}
//********************************
};
[![top of receipt][1]][1]
[![bottom of receipt][2]][2]
[1]: https://i.stack.imgur.com/wouq6.png
[2]: https://i.stack.imgur.com/Tq5tT.png
In your main you create a new cartManager for each thread. I believe it is not what you did on purpose.
threads.emplace_back
(
&cartManager::processCarts, cartManager(),
ref(dataBase), ref(all_queues[q])
);
Instead of passing cartManager() pass &manager. Why it is important? Because of creating a brand new cartManager for each thread, your function has a different this context. That means, all your threads has its own dataBaseMut - so nothing is synchronized between your threads because of that!
You don't need to modify dataBase in processCarts - in that case, pass it by const reference: in that case, it's obvious to other people (and to you) that it is not something that may be modified in processCarts.
Now opening the file is synchronized (in case you fix the very first issue I described in this answer), but only opening! Writing to the file is not synchronized, so there is a chance that your threads write to the same file simultaneously. What may happen in that case? A mess! Thus, not only opening the file should be synchronized, but writing as well. I would suggest creating a class that is in charge of writing to a file and is thread safe (it's safe to call its methods from different threads). And that class would take care of synchronizing the access to a file.
It's hard to say without the whole source code, but what is wrong in your code is that opening of your file outFile is not protected by your mutex. This should be a reason why you have a mess in your file.
Related
I'm currently learning C++ and I'm trying to complete a recursive function, which first reads a data-structure and then returns itself n-amount of times to the main function. These returns are supposed to be summed up in the main-function and assigned to a variable.
In my program I have a little trickier data-structure. It is a Map, which consists of string and a vector-string. The purpose of the data-structure is to display a pyramid scheme: all the people associated with the leaders of the pyramid scheme.
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
int recursive_function(map<string, vector<string>> data_structure, string id)
{
// Going trough every name associated with the current id-name.
for (auto& name : data_structure[id])
{
// Recalling the function, when the current name is associated to the
// first name-id declared in the main function (Hugo).
recursive_function(data_structure, name);
}
// Returning the function, every time a single associate has been found.
// In this case, we get 10 associates with Hugo, which means the recursive
// function will be returned a total of 11 times (1 of these returns will be
// ignored, since Hugo can't be an associate with himself in the example...
cout << "Now returning." << endl; // This is just for clarity.
return 1;
}
int main()
{
// Creating the data-structure, which displays a pyramid scheme. It can be
// used to navigate trough connections between the people.
map<string, vector<string>> data_structure;
data_structure = {
{"Hugo", {"Laura", "Jasper"}}, // Hugo is one of the leaders. He is
// associated with Laura and Jasper, who
// are associated with others etc. Laura
// and Jasper too are one of the leaders.
{"Laura", {"Helena", "Elias"}},
{"Jasper", {"Maria", "Bibek", "Raul"}},
{"Helena", {"Sofia", "Amelia", "Rick"}},
{"Sofia", {}}
};
string id = "Hugo";
int associate_counter = 0;
associate_counter += recursive_function(data_structure, id);
cout << "Hugo has a total of "
<< associate_counter - 1 // Should print the equation 10-1 (10), but
<< " associates." // instead, prints 1-1 (0).
<< endl;
return 0;
}
What am I doing wrong. Why can't I sum up the functions return times in the main functions associate_counter variable, by using recursion?
You're just discarding the values returned from all the calls to recursive_function. You need to add them up.
Example:
int sum = 0;
for (auto& name : data_structure[id])
{
sum += 1 + recursive_function(data_structure, name);
// + 1 for the associate
// + the sum of the associate's associates (recursively)
}
return sum;
This will make it return 10 for Hugo.
Demo
I am getting a segmentation fault for this code in a web-based editor, but not in XCode. I am not that familiar with these errors, but I looked it up and couldn't identify the problem. One other difference is that I remove the main method when I use the web editor. Does anyone know what the problem is? Thanks in advance.
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
using namespace std;
class Lexer
{
public: vector <string> tokenize(vector <string> tokens, string input);
};
vector <string> Lexer::tokenize(vector <string> tokens, string input)
{
vector <string> consumed;
if(tokens.size()>50)
{
tokens.resize(50);
}
//The next section sorts the tokens from largest to smallest
int swap_count = 0; //this tracks whether the sort needs to happen again
do
{
swap_count = 0; // set the swap count to zero
for(int i=0; i<tokens.size(); i++) //loop that runs the length of the 'tokens' string
{
if(tokens[i].length()<tokens[i+1].length()) // if this token is smaller in length than the next token
{
tokens[i].swap(tokens[i+1]); //swap the tokens
swap_count++; //add one to the swap count
}
}
}
while(swap_count!=0); //while there are swaps
//The next section consumes the input string.
while(input.length()>0)
{
int count_tokens_consumed=0;
for(int i=0; i<tokens.size(); i++) // loop set up to go through the units in the tokens vector
{
if(tokens[i]==input.substr(0,tokens[i].length())) //if the current token matches the first part of the input
{
consumed.push_back(tokens[i]); //add the token to the consumed vector
input = input.substr(tokens[i].length()); //remove the token from the front of the input string
count_tokens_consumed++;
i=int(tokens.size());
}
}
if (count_tokens_consumed==0)
{
input = input.substr(1);//or remove the first character on no match
}
}
return consumed;
}
int main()
{
Lexer LexerOne;
vector <string> LexerOne_out = LexerOne.tokenize({"AbCd","dEfG","GhIj"},"abCdEfGhIjAbCdEfGhIj");
for(vector<string>::iterator i = LexerOne_out.begin(); i != LexerOne_out.end(); ++i)
cout << *i << " ";
return 0;
}
Whether the segmentation fault was ignored in one environment, but not another is irrelevant.
The action leading to the segmentation fault is undefined behaviour.
The following line of code:
line 31: tokens[i+1].length()
Is not a valid index into your tokens.
This is because you are iterating from 0 to tokens.size().
The range of valid indexes into tokens would be from 0 to tokens.size()-1.
if(tokens[i].length() < tokens[i+1].length())
The i+1 index is out of bounds.
Now to answer as to why you get one behavior when running on one compiler than another, going out of bounds with a vector leads to undefined behavior. Anything can happen, including "work correctly all the time", "work sometimes, crash other times", "crashes all the time", "work on your computer but not another computer", etc.
If you want consistent behavior when you go out of bounds, use std::vector::at() instead of [ ] when accessing the elements of your vector.
if(tokens.at(i).length() < tokens.at(i+1).length())
If you did that, you would have received an std::out_of_range exception on both compilers (if the input is the same) instead of a random segmentation fault.
If you write code that uses std::vector, and you are not using pointers to any great extent, a lot of segmentation fault issues occur due to going out-of-bounds of the vector. So what I usually recommend is to replace [ ] with at() to pin down any boundary issues first. If there are issues, then they get cleaned up first. Once cleaned up, then the [ ] is reintroduced into the code (since [ ] does no bounds checking, it will run faster than the same call to at()).
I'm making a class-based inventory system using two classes: one for characters and one for items.
Code by Ryan Newell - NEW14136796 Uclan Student
(Need to put this in so plagarism monitors won't flag me for copying my own work)
Here's what I got so far.
///Code by Ryan Newell - NEW14136796 Runshaw College - Uclan
#include<iostream> //Base C++ required #
#include<string> //Allows input of strings
#include<iomanip> //Base C++ required #
#include <conio.h> //Getchar error workaround
#include <cstdlib> // Provides EXIT_SUCCESS
#include <fstream> // Allows output of txt files
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <utility>
#include <Windows.h>//ConsoleSleep
using namespace std;
class itemspell{
string itemname; //Name ((( what if items are the same name ? make difficult for finding statements ? maybe more char with same name item ?
string itemtype; // Spell/Weapon/Armour/Magic Misc?
string itemact; // What type of action does this item do ?
string itemdesc; // Some random ingame description
itemspell* inext; //The next pointer location
bool isspell; //Is Spell Boolean
bool isweapon; // Weapon
bool isarmour; // So on so forth
bool ismisc; // Misc
bool offensiveitem; //Offensive item
bool defensiveitem; // defensive item
bool passiveitem; // Passive effect
int damage;
int armour;
int magicbonus;
int magicresistance;
int cost;
void item_spellsearch(itemspell* ihead, itemspell* &ipast, itemspell* &icurrent)
{
string search;
if (ihead==NULL)
{
cout<<"There are no items on the list to search"<<endl;
}
else
{
cout<<"Enter the type item you are searching for :"<<endl;
getline(cin,search);
icurrent=ihead; //current pointer goes to -> header
cout<<icurrent<<" "<<search<<" "<<icurrent->itemtype<<endl;
while(icurrent!=NULL && search>icurrent->itemname)
{
cout<<"Item Type:"<<icurrent->itemtype<<" "<<cout<<icurrent->itemname<<endl;
ipast=icurrent; //Past = new current pointer
icurrent=icurrent->inext; //current pointer = next pointer
}
}
}
public:
itemspell()//Building a new item // -- Cannot put byref / by values in here remember, needs to be default constructor for some reason ??
{
cout<<"Enter Item Type: "<<endl;
getline(cin,itemtype);
cout<<"Enter Item Name: "<<endl;
getline(cin,itemname);
cout<<"Enter Item Description: "<<endl;
getline(cin,itemdesc);
cout<<"Enter Item Action :"<<endl;
getline(cin,itemact);
}
~itemspell()//Delete record output
{
cout<<"Item being deleted"<<endl;
Sleep(500);
cout<<"Item deleted"<<endl;
getch();
}
void additemspell(itemspell* &ihead) // Add record code
{
itemspell *icurrent;
itemspell *ipast;
itemspell *newitem;
newitem = new itemspell; // New itemspell
if (ihead == NULL || newitem->itemname<ihead->itemname) //If no header or itemname is null;
{
newitem->inext = ihead;
ihead = newitem;
}
else
{
icurrent= ihead;
while(icurrent !=NULL&&icurrent->itemname<newitem->itemname) // While the current char Does not equal NULL/"Nothing and charcurrent itemname = newitemitemname"
{
ipast=icurrent;
icurrent=icurrent->inext;
}
newitem->inext=icurrent; // Sets the next char to current and the past char to next to add in new record.
ipast->inext=newitem;
}
}
void deleteitemspell(itemspell* &ihead) /// Getting the address of the itemspell not the itemspell itself
{
itemspell *ipast=NULL, *icurrent=NULL;
item_spellsearch(ihead, ipast, icurrent);
if(ihead!=NULL)
if(icurrent==NULL)
{
cout<<"ERROR: No itemspell Found"<<endl;
Sleep(500);
cout<<"returning to menu... press enter"<<endl;
getch();
}
else
{
if (icurrent == ihead)
{
ihead = ihead->inext;
}
else
{
ipast->inext=icurrent->inext; //Resets the pointer and header's back to previous positions....
delete icurrent;// Calls the deletion of the itemspell entry.
cout<<"itemspell found was deleted press enter to confirm"<<endl;
getch();
}
}
}
class character
{
string forename;
string surname;
string nickname;
string race;
string alignment;
string alignment_type;
string character_class;
int Strength; //Strength
int Intelligence; //Magick 2
int Willpower; //Magick 1
int Endurance; //Health
int Agility; //Agility
int StartingWealth; //StartingWealth
character* char_itemp; // Character - Item pointer - Adress location of the characters items
character* char_next; // Next Pointer Value- Points to the location of the next person in the Dynamic Linked List
What I'm trying to do is when I create a new item, I want to be able to give that item to a character to use.
I know somewhere along the lines of I need to create a pointer value in the character class to point to the itemspell class but I am unsure what to do and could do with some help.
Essentially I want to get the character class to point to the item class when the item class is called from the constructor within the item class.
Please, if you can, don't give just code. Rather, please highlight areas where I should change and give suggestion examples. My degree program is strict about plagiarism.
Pseudo Code
When newitemspell created
get input charactername ()
:
if no current itemspell created for that character
add item to
character->charactername
else
add item to next pointer character->charactername
By looking at your code and looking at the descriptor of what you're trying to accomplish, why don't you just create an Inventory class to handle a users items? It should be able to handle 99% of anything you're wanting to do. Let me know if this example is anything like what you're trying to do.
To be completely honest, I have nary a clue what it is exactly you're trying to do in your code. As a previous user mentioned, "linking" two classes is a simple matter of giving the base class a variable of the required class. For example:
#include <vector> //I prefer to use vectors for just about any list of objects.
//It's just more convenient for me.
using std::vector;
class Inventory //A handler for all of your character's stuff.
{
private:
vector<object_class> objs; //To actually store an array of whatever objects
//you need to.
//Just some example functions to make the class useful.
public:
int MAX = -1; //The size limit for the inventory. This can be used as a useful
//statistic in the specific inventory, depending on how it's being
//used. My example shows the value at -1, which, at least for me,
//means that any maximum size checks being done won't bother it
//because I usually have a setting of -1 as being unlimited.
getItem(int slot); //Return item
removeItem(int slot) //Removing items
addItem(object_class object) //Adding items
}
This is just really simple programming from here. All you need to do is create variables with the type of Inventory. Any reference to an object_class is just a generic fill-in for the class type of whatever object you're wanting the Inventory to handle. This will most likely be a base class while you're using derivatives.
class Character //The character class with all kinds of stuff to needs to be handled
{
public:
Inventory items; //A regular inventory bag for items.
Inventory equip; //The items the character is currently using.
Inventory spells; //An alternate use for Inventory to be used as a handler for
//spell lists and other cool stuff.
}
And from here you should be able to understand what exactly is going on. Inventory isn't "linked" to Character. Character has three variables with the type Inventory and the Inventory class itself will handle all of the adding, removing, sorting and retrieving of items in its vector.
Now you can make everything work like so:
int main(int argc, char *argv[])
{
Character player;
Armor shield = new Armor(); //A dummy object
player.items.addItem(shield); //Assuming the Inventory is setup to handle Armor items.
//This will add the shield to the player's inventory.
player.items.MAX = 10; //Setting the maximum capacity of items to 10, obviously.
Armor A = player.items.getItem(0); //returns the piece of armor in the first spot in the vector.
}
I would normally write way more modular code for something like this, such as making Inventory a template class, but I digress. This was just to show you how to attach one class object to another.
I hope this was remotely like what you were searching for. If not, please try rewriting your question a little more specifically.
I am writing a program for homework. I have the following code. The requirements are as follows:
Your Community Supported Agriculture (CSA) farm delivers a box of fresh fruits and vegeta-bles to your house once a week. For this programming project, de ne the class BoxOfProduce that contains exactly three bundles of fruits or vegetables. You can represent the fruits or vegetables as an array of type string. Add appropriate constructors and accessor/mutator functions to get or set the fruits or vegetables stored in the array. Also write an output function that displays the complete contents of the box on the console.
Next, write a main function that creates a BoxOfProduce with three items randomly selected from this list:
Broccoli
Tomato Kiwi
Kale
Tomatillo
Do not worry if your program randomly selects duplicate produce for the three items. Next, the main function should display the contents of the box and allow the user to substitute any one of the ve possible fruits or vegetables for any of the fruits or vegetables selected for the box. After the user is done with substitutions it should output the nal contents of the box to be delivered. Then it should ask if the user wants to create another box and if yes, it should repeat the above steps. It should keep doing so until the user chooses not to create another box of produce.
Finally, add a static variable to your class that keeps track of the total number of boxes of produce created and a static function that returns that value. Display this value in the main function at the end of each iteration of the main loop.
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
class BoxOfProduce
{
public:
BoxOfProduce();
void displayWord(int boxee);
void input();
void output();
string Box[];
private:
string full_list[5];
static int count;
};
int BoxOfProduce::count=0;
BoxOfProduce::BoxOfProduce()
{
full_list[0] = ("Broccoli");
full_list[1] = ("Tomato");
full_list[2] = ("Kiwi");
full_list[3] = ("Kale");
full_list[4] = ("Tomatillo");
}
void BoxOfProduce::input()
{
}
void BoxOfProduce::output()
{
cout<<"your bundle: ";
for(int i=0; i < 3; i++)
{
srand(time(0));
int boxee = rand()% 5;
Box[i] = full_list[boxee];
displayWord( boxee);
}
}
void BoxOfProduce::displayWord(int boxee)
{
cout << Box[boxee]<<endl;
}
int main()
{
BoxOfProduce b1;
b1.input();
b1.output();
}
When I run the program, it shows no errors or exceptions, the program compiles, starts and then a Windows error pops up and says "The program has stopped running." Does anyone see anything wrong with this?
I need to make some design docs- I'm at a loss to decide on data-type and process issues ...i know there are far more experienced designers who can help me find a KISS-simple ADT or template that i haven't been able to find so lets start with requirements:
The main function retrieves resumes and ranks them from MOST to Least based on:
**User-defined keywords** that are assigned an int Value
//the best type seems to be pairing:
template <class udKeyword, class IntValue>
class Pair{
Public: udKeyword one; IntValue two;
}
//note ...a PairList class is also req'd
The ranked_doc_list needs to be massively scalable so I am unsure whether to call a sort when the user requests the ranked_doc_list or if res_docs should insert themselves (and push_back lower-ranked res_docs) as they come in. that approach seems best but also seems like a lot of waste in terms of computation and memory.
I'm starting with a very simple example.
The client is going to enter udKeywod/Value pairs My_client_company will post
"Experienced Bartender needed - please email resume to client#xxxxx.yyy"
assume "Experienced" = 7, "Bartend" = 5, "Bartending" = 5, "Customer Service" = 4, "Diploma" = 3... ...etc. (an enumeration)
I would prefer the resumes come in as .doc files that I can break down by **resume_filename** and build a template for each document as opposed to making it functional as well:
/*FORGIVE MY C++ STL (untested - I'm on a laptop running Win7 that
makes me miss my HP-UX and SParc-Solaris Labs greatly*/
//extract the file name and parse/allocate the text into a CSV array
template <class filename, class CSV_unordered_list>
class doc_data_pull{
public:
string name() = new resdoc.filename;
int wordQty = CSv_unordered_list.get_size();
string csv[];
void getCSVarray{
for(int i=0; i < wordQty; CSV_unordered_list.next(); i++){
csv[i] = CSV_unordered_list.get_string();
}
}
//compare csv array using a strcompare wwith udKeywords and assign a score to name
template <class PairList; class doc_data_pull;>
class ranksResume{
getCSV_matches_and scores(csv[]; name();{
int PLsize = Pairlist.size();
int i=0;
int score[] = 0;
int PLindex = 0;
while (PLindex < Pairlist.size();{
if (csv[i] == Pairlist.udKeyword()** //string-compare is the centerpiece of the logic
score = Pairlist.score //the user-defined keyword matched
i++; Pairlist.next();
PLindex++;}
else{i++; PLindex++;}}//end else and while
//report the score and name() for QC sanshot
cout<< name() /*should be initial filename uploaded to /root */ << scored a << score \n;
//a listype for **ranksResume is also skipped over due to laziness**
#include "udKeyword.h" //for user to define keywords per job posting
#include "intKey.h" //an integer value with a unique identifier to prevent "ties"
#include "pair.h" //keyword, value from user
#include "pairlist.h" //user-defined and created listype Keyword and Relevance metric
#include "filename.h" //extracts the text "filename" or 1st txt line for txt-only resumes
#include "CSVunorderdList.h" //creates a CSV array for str-compare to udKeyword
#include "doc_data_pull.h"//provides CSV for each doc AND the resume-filename
#include <iostream>
#include <string>
#include "ranksResume.h" //WIP
using namespace std;
int main(){//I have almost no recollection of switches in the .cpp so bear w/ me
char input;
cout << "What would you like this bogus document-SEO-based idea of yours to do? <<endl;
cin >> input;
switch(a, b, c, d, e, f, g, h) {
case a : Add a new Keywored
case b : change the value of a Keyword
case c : you have << filename.size() << new resumes. Display all? << ranksResumeList.print()'
Case d : display just the top 10. << ranksResumeList.printTopTen();
case e : delete a resume
case f : favorite a resume
case g : mark this job search complete
case h : exit.}
return 0;
//take benzodiazepenes
}//end main
Anyway that is probably my first pile of object code in a decade. It's partial, probably loaded with bugs and type-missmatch ... but you can prob see where my pseudocode-solution are headed I did search for this a week ago an found very little posts or comments of worth on paired data lists that define the rank of documents (or strings, objects....) based on a robotic selection of keywords and subjective weight to develop "relevance" it's bs but customers really want to sort client documents this way...it's institutionalized SEO corruption but whatever...I'll work on anything for a few bucks.As designers though....I really want to know which algorithms and ADTs you would use to solve this.DONT feel obligated to give answers in C/C++/Java...plus I never touched on how a (php?) function I'd would implement the receipt and likely sorting/indexing of .doc files.