I'm trying to compress a file consisting of 1's and 0's as part of an assignment. I have succeeded in doing this, however to get a feel for threads I'm trying to display a simple progress display using a pthread. The problem is that the thread executes AFTER the compression is complete. Here is my program:
void* compressShow(void *)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
cout<<"Compressing";
while(1)
{
sleep(1);
cout<<".";
sleep(1);
cout<<".";
sleep(1);
cout<<".";
sleep(1);
cout<<".";
cout<<"\b\b\b\b";
}
}
void compression(char *buffer, ofstream &outFile)
{
//Some Compression code. Function executes each time a new line is lifted off the file.
}
int main(int argc, char *argv[])
{
if(argc < 3)
{
cout<<"You entered an insufficient number of command line arguments."<<endl;
}
else
{
ifstream inFile;
inFile.open(argv[1], ios::in);
ofstream outFile(argv[2]);
char buffer[100] = {NULL};
pthread_t thread;
pthread_attr_t attribute;
pthread_attr_init(&attribute);
pthread_attr_setdetachstate(&attribute, PTHREAD_CREATE_DETACHED);
pthread_create(&thread, &attribute, compressShow, (void *)5);
while(inFile.good())
{
` inFile.getline(buffer, 100, '\n');
compression(buffer, outFile);
}
pthread_cancel(thread);
//pthread_join(thread, NULL);
}
return 0;
}
Since I'm creating the thread BEFORE the while loop, I expect it to run concurrently with the loop that is doing the compression.
This has nothing to do with threads. See the same effect with
int main()
{
compressShow(0);
}
Try sending the flush manipulator from time to time.
Related
I am just putting the code here for the execute procedure
There exists a structure which contains a member char* command_list[MAXCOMMANDS][MAXARGUMENTS]
The first position of each row in this member contains the command and the rest of the items in the row are arguments
I have made the execute procedure which on giving the input ls | wc gives **
DUP2 HERE : Bad file descriptor
Structure below
struct command
{
ifstream input;
ofstream output;
int num_commands=-1;
int num_args[MAXCOMMANDS]={0};
char* command_list[MAXCOMMANDS][MAXARGS]; //command and their arguments storage
vector<string> pr_operator; //Pipe or redirection operators storage
bool background_task;
bool append;
};
Execute function below
int execute()
{
pid_t pid,wpid;
int status;
int num_pipes=count_pipes();
int pfds[2*num_pipes];
for(int i=0;i<num_pipes;i++)
{
if(pipe(pfds+2*i)<0)
{
perror("Cannot Pipe");
exit(1);
}
}
for(int i=0,j=0;i<=s.num_commands;i++,j+=2)
{
pid=fork();
if(pid==0)
{
if(i>0) //if not first command
{
if(dup2(pfds[j-2],0)<0)
{perror("DUP2 HERE");exit(1);}
close(pfds[j-2]);
close(pfds[j-1]);
}
if(i<s.num_commands) // if not last command
{
if(dup2(pfds[j+1],1)<0)
{perror("DUP2");exit(1);}
close(pfds[j+1]);
close(pfds[j]);
}
if(execvp(s.command_list[i][0],s.command_list[i])==-1)
{
perror("My Shell");
exit(1);
}
}
else if(pid<0)
{
perror("My Shell");
exit(1);
}
else
{
for(int k=0;k<2*num_pipes;k++)
close(pfds[k]);
for(int k=0;k<num_pipes+1;k++)
wait(&status);
}
}
return 1;
}
I need some algorithm help with a multithreaded program I'm writing. It's basically the cp command in unix, but with a read thread and a write thread. I'm using semaphores for thread synchronization. I have structs for buffer and thread data defined as
struct bufType {
char buf[BUFFER_SIZE];
int numBytes;
};
struct threadData {
int fd;
bufType buf;
};
and a global array of bufType. Code for my main is
int main(int argc, const char * argv[])
{
int in, out;
pthread_t Producer, Consumer;
threadData producerData, consumerData;
if (argc != 3)
{
cout << "Error: incorrect number of params" << endl;
exit(0);
}
if ((in = open(argv[1], O_RDONLY, 0666)) == -1)
{
cout << "Error: cannot open input file" << endl;
exit(0);
}
if ((out = open(argv[2], O_WRONLY | O_CREAT, 0666)) == -1)
{
cout << "Cannot create output file" << endl;
exit(0);
}
sem_init(&sem_empty, 0, NUM_BUFFERS);
sem_init(&sem_full, 0, 0);
pthread_create (&Producer, NULL, read_thread, (void *) &producerData);
pthread_create (&Consumer, NULL, write_thread, (void *) &consumerData);
pthread_join(Producer, NULL);
pthread_join(Consumer, NULL);
return 0;
}
and read and write threads:
void *read_thread(void *data)
{
threadData *thread_data;
thread_data = (threadData *) data;
while((thread_data->buf.numBytes = slow_read(thread_data->fd, thread_data->buf.buf, BUFFER_SIZE)) != 0)
{
sem_post(&sem_full);
sem_wait(&sem_empty);
}
pthread_exit(0);
}
void *write_thread(void *data)
{
threadData *thread_data;
thread_data = (threadData *) data;
sem_wait(&sem_full);
slow_write(thread_data->fd, thread_data->buf.buf, thread_data->buf.numBytes);
sem_post(&sem_empty);
pthread_exit(0);
}
So my issue is in what to assign to my threadData variables in main, and my semaphore logic in the read and write threads. I appreciate any help you're able to give
Being a windows guy who does not use file descriptors I might be wrong with the in's and out's but I think this needs to be done in your main in order to setup the threadData structures.
producerData.fd = in;
consumerData.fd = out;
Then declare ONE SINGLE object of type bufType for both structures. Change for example the definition of threadData to
struct threadData {
int fd;
bufType* buf;
};
and in your Main, you write
bufType buffer;
producerData.buf = &buffer;
consumerData.buf = &buffer;
Then both threads will use a common buffer. Otherwise you would be writing to the producerData buffer, but the consumerData buffer will stay empty (and this is where your writer thread is looking for data)
Then you need to change your signalling logic. Right now your program cannot accept input that exceeds BUFFER_SIZE, because your write thread will only write once. There needs to be a loop around it. And then you need some mechanism that signals the writer thread that no more data will be sent. For example you could do this
void *read_thread(void *data)
{
threadData *thread_data;
thread_data = (threadData *) data;
while((thread_data->buf->numBytes = slow_read(thread_data->fd, thread_data->buf->buf, BUFFER_SIZE)) > 0)
{
sem_post(&sem_full);
sem_wait(&sem_empty);
}
sem_post(&sem_full); // Note that thread_data->buf->numBytes <= 0 now
pthread_exit(0);
}
void *write_thread(void *data)
{
threadData *thread_data;
thread_data = (threadData *) data;
sem_wait(&sem_full);
while (thread_data->buf->numBytes > 0)
{
slow_write(thread_data->fd, thread_data->buf->buf, thread_data->buf->numBytes);
sem_post(&sem_empty);
sem_wait(&sem_full);
}
pthread_exit(0);
}
Hope there are no more errors, did not test solution. But the concept should be what you were asking for.
You could use a common buffer pool, either a circular array or a linked lists. Here is a link to a zip of a Windows example that is similar to what you're asking, using linked lists as part of a inter-thread messaging system to buffer data. Other than the creation of the mutexes, semaphores, and the write thread, the functions are small and simple. mtcopy.zip .
I am using c++ 11 on windows platform, and i wanted to know how to open a new console window to display output from a child thread.
mutex mu;
bool flag = false;
void printg()
{
int j=printf("testing /");
int count=0;
for(int i=0;true;)
{
sleep(1.0);
printf("\b");
printf("\\");
fflush(stdout);
sleep(1.0);
printf("\b");
printf("/");
fflush(stdout);
count++;
lock_guard<mutex> gaurd(mu);
if(flag)
{
return;
}
}
}
int main(int argc, char** argv)
{
thread t(printg);
pid_t p ;
sleep(5);
mu.lock();
flag = true;
mu.unlock();
t.join();
cout<<endl<<"hello "<<endl;
return 0;
}
I want the output of thread t on a different window and/or console, separate from the parent thread. In the long run i want to detach the thread and make it powerful enough to display output on its own window. Is there a work around this. I am working on windows 7 machine.
Here is my main function i use visual studio 2012 express and the code works fine. My question is how will i terminate this loop when the user Presses the ESC button instead of -1. Although i would prefer a solution that works both in unix and windows, if it is not possible i am most interested in it working for windows.
int _tmain(int argc, _TCHAR* argv[])
{
list mylist;
int value;
cout<<"Give the numbers you want to insert to the list, press -1 to stop\n";
do
{
cin>>value;
mylist.insertf(value);
mylist.sort_list();
mylist.print();
}while(value!=-1);
}
Here are solution for Windows
First solution:
Esc will not be handled when user starts to type till pressing enter.
While idle Esc will be handled
#include <Windows.h>
#include <iostream>
#include <conio.h>
#include <vector>
int main(int argc, char **argv)
{
int value=0;
std::vector<int> mylist;
do
{
//check if any input.
if (_kbhit()){
//probable user started to type
//block to read till the user press Enter. If you want to handle Esc here .
//then you should manually do input reading . I will write that solution later
std::cin>>value;
//if success
if(std::cin.good()){
mylist.push_back(value);
}else{
//firstly, clear error flag
std::cin.clear();
//ignore
std::cin.ignore(10000,'\n');
}
//print list
std::cout<<"new list: { " ;
for(int i=0;i< mylist.size();i++){
std::cout<<mylist[i]<<'\t';
}
std::cout<<" }"<<std::endl;
}
//check if Esc Pressed
}while(GetAsyncKeyState(VK_ESCAPE)==0);
return 0;
}
Second Solution:
Esc will be handled always in another thread. Immediate exit can be undesirable on some cases
DWORD WINAPI CheckEscape( LPVOID lpParam ) {
while(GetAsyncKeyState(VK_ESCAPE)==0){
//sleep
Sleep(10);
}
exit(0);
}
int main(int argc, char **argv)
{
int value=0;
std::vector<int> mylist;
//create thread for handling ESC key
CreateThread( NULL, 0, CheckEscape,NULL , 0, NULL);
//loop infinitely
while(true)
{
std::cin>>value;
//if success
if(std::cin.good()){
mylist.push_back(value);
}else{
//firstly, clear error flag
std::cin.clear();
//ignore
std::cin.ignore(10000,'\n');
}
//print list
std::cout<<"new list: { " ;
for(int i=0;i< mylist.size();i++){
std::cout<<mylist[i]<<'\t';
}
std::cout<<" }"<<std::endl;
}
return 0;
}
Third Solution and the Best one .Do everything manually
Handling keypress manually.
Exit will be called when Esc is Pressed. You can change it to handle more right way
bool keypress( char &key){
INPUT_RECORD IR[1];
DWORD read;
static HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
while(PeekConsoleInputA(h,IR,1,&read)){
if(read!=0){
//check if it was Key Event
if(IR[0].EventType==KEY_EVENT){
key=IR[0].Event.KeyEvent.uChar.AsciiChar;
ReadConsoleInputA(h,IR,1,&read);
FlushConsoleInputBuffer(h);
return true;
}
if(ReadConsoleInputA(h,IR,1,&read)){
continue;
}
}else{
return false;
}
}
}
//getnumber
int cinnumb( ){
char buffer[32];
buffer[0]='\0';
int count=0;
DWORD key=-1;
while(true){
Sleep(100);
do{
//here I make it nonblockin keypress
//but actually we do not need it
//we can use blocking ReadConsoleInputA(h,IR,1,&read);
//this way we not even need sleep() and
//our keypress function will be simple
//anyway im posting nonblocking one
//nonblocking keypress
char key=0;
bool isOk=keypress(key );
if(!isOk ){
Sleep(20);
continue;
}
if(key>='0' && key<='9'){
buffer[count]=key;
std::cout<<key;
++count;
if( count==31)break;
}
// check Enter key and enough symbol
if( key==13 && count>0 ){
std::cout<<std::endl;
break;
}
//for windows
//check if Esc pressed
if(key==27) exit(0);
}while(true);
buffer[count]='\0';
int value=atoi(buffer);
return value;
}
}
int main(int argc, _TCHAR* argv[])
{
std::vector<int> mylist;
int value;
char buffer[100];
//infinite loop
while(true)
{
//get number
value=cinnumb();
mylist.push_back(value);
//print list
std::cout<<"new list: { " ;
for(int i=0;i< mylist.size();i++){
std::cout<<mylist[i]<<'\t';
}
std::cout<<" }"<<std::endl;
//sleep a little
Sleep(10);
} ;
return 0;
}
#include <cstdio>
#include <QtCore/QProcess>
int main (int argc, char** argv) {
// if we remove 3 following lines, the problem described below doesn't exists!!
QProcess process;
process.start ("asdqwe"); // doesn't matter what we try to execute here.
process.waitForStarted (1000);
while (true) {
char buf[100];
if (scanf ("%s", buf) == EOF) { // it looks like stdin is closed!
printf("FAIL\n");
return 1;
}
printf ("%s\n", buf);
}
return 0;
}
This code is just a snippet to show the problem. In the full application I need read/write communication with process.
I compile it with:
g++ -o out ./main.cpp -I /usr/include/qt4/ -lQtCore
And execute it from bash command line in terminal.
Why this program sometimes prints FAIL and sometimes will stay in loop?
Edit:
This is not question about scan/printf.
The same problem is if I use iostreams + string. This question is about interaction of QProcess with file descriptors of parent process.
Your scanf was interrupted by SIGCHLD signal that was caught when child process terminated. In this case EOF is also returned.
QProcess stuff does set up signal handler for SIGCHLD (check sources): (4.5.3 here)
Q_GLOBAL_STATIC(QProcessManager, processManager)
QProcessManager::QProcessManager()
{
#if defined (QPROCESS_DEBUG)
qDebug() << "QProcessManager::QProcessManager()";
#endif
// initialize the dead child pipe and make it non-blocking.
// (pipe and fcntl skipped - P. Shved.)
// set up the SIGCHLD handler, which writes a single byte to the dead
// child pipe every time a child dies.
struct sigaction oldAction;
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_handler = qt_sa_sigchld_handler;
action.sa_flags = SA_NOCLDSTOP;
::sigaction(SIGCHLD, &action, &oldAction);
if (oldAction.sa_handler != qt_sa_sigchld_handler)
qt_sa_old_sigchld_handler = oldAction.sa_handler;
}
#include <cstdio>
#include <QtCore/QProcess>
int main (int argc, char** argv) {
// if we remove 3 following lines, the problem described below doesn't exists!!
QProcess process;
process.start ("asdqwe"); // doesn't matter what we try to execute here.
process.waitForStarted (1000);
while (true) {
char buf[100];
if (scanf ("%s", buf) == EOF) { // it looks like stdin is closed!
if (errno == EINTR) {
errno = 0;
continue;
}
printf("FAIL\n");
return 1;
}
printf ("%s\n", buf);
}
return 0;
}
I really use streams, I had to use
cin.clear();
errno = 0;