C++ console application async accepting user input - multithreading

I recently stumbled upon this
link and I just tried it, but it's not working as I expect.
With this code:
#include <atomic>
#include <thread>
#include <iostream>
void ReadCin(std::atomic<bool>& run)
{
std::string buffer;
while (run.load())
{
std::cin >> buffer;
if (buffer == "q")
{
run.store(false);
}
}
}
int main()
{
std::atomic<bool> run(true);
std::thread cinThread(ReadCin, std::ref(run));
while (run.load())
{
// some lengthy operation
}
run.store(false);
cinThread.join();
return 0;
}
In the main While loop, I have an object of a class that is doing some lengthy operation, one which I'm trying to stop with the letter "q" coming from the user. When I type "q", i see the "run.store(false);" hit in the ReadCin method, but this doesn't break me off from the main while loop. What am I doing wrong?

Related

cpp thread detach position?

my simple test code here:
// t.cpp
#include <iostream>
#include <chrono>
#include <thread>
void fcn()
{
uint8_t i = 0;
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout<<"hihi" << float(i++)<<std::endl;
}
}
std::thread t(fcn);
t.detach(); // detach position A
int main()
{
// t.detach(); // detach position B
uint8_t i = 0;
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout<<"yoyo" << float(i++)<<std::endl;
}
}
compile and run by g++ ./t.cpp -o t -lpthread; ./t;
when detach at position A got compile error error: ‘t’ does not name a type | t.detach();,
but detach at position B is ok.
why is this different?
my situation is that i wish to move the fcn() and std::thread t(fcn) as well as t.detach() into a standalone header file later (for a better orginazation of the project) thanks

Error when starting thread with CreateThread [duplicate]

This question already has answers here:
incompatible types when creating thread in Windows
(1 answer)
Conversion error in CreateThread
(1 answer)
Closed 4 years ago.
I am trying to create a scheduler, and when creating a thread, it gives the following error:
argument of type "DWORD (*)(LPVOID lpParameter)" is incompatible with parameter of type "LPTHREAD_START_ROUTINE".
I made the thread function static as suggested in other questions and it still gives the same error. Any solution or pointers would be appreciated.
This is the relevant part of my code:
#include "stdafx.h"
#include <string>
#include <windows.h>
#include <vector>
#include <stdio.h>
#include <thread>
using namespace std;
struct process {
int PID = 0;
int burstTime;
int arrivalTime;
int priority;
};
vector<process> allProcesses;
process myProcess;
vector<HANDLE> handles;
vector<DWORD> dwords;
static DWORD myThread(LPVOID lpParameter)
{
//execute my thread
}
void newArrival()
{
DWORD tempThreadID;
dwords.push_back(tempThreadID);
////error happens here at myThread
handles.push_back(CreateThread(0, 0, myThread, &allProcesses[0], 0, &dwords[dwords.size() - 1]));
//do even more stuff
}
void scheduler()
{
//do some other stuff
newArrival();
//do more stuff
}
int main()
{
//do some stuff
myProcess.arrivalTime = 1000;
myProcess.burstTime = 2500;
myProcess.priority = 90;
allProcesses = {myProcess};
thread scheduler(scheduler);
system("PAUSE > null");
return 0;
}

Issue in predicate function in wait in thread C++

I am trying to put the condition inside a function but it is throwing confusing compile time error . While if I write it in lambda function like this []{ retur i == k;} it is showing k is unidentified . Can anybody tell How to solve this problem .
#include <iostream>
#include <mutex>
#include <sstream>
#include <thread>
#include <chrono>
#include <condition_variable>
using namespace std;
condition_variable cv;
mutex m;
int i;
bool check_func(int i,int k)
{
return i == k;
}
void print(int k)
{
unique_lock<mutex> lk(m);
cv.wait(lk,check_func(i,k)); // Line 33
cout<<"Thread no. "<<this_thread::get_id()<<" parameter "<<k<<"\n";
i++;
return;
}
int main()
{
thread threads[10];
for(int i = 0; i < 10; i++)
threads[i] = thread(print,i);
for(auto &t : threads)
t.join();
return 0;
}
Compiler Error:
In file included from 6:0:
/usr/include/c++/4.9/condition_variable: In instantiation of 'void std::condition_variable::wait(std::unique_lock<std::mutex>&, _Predicate) [with _Predicate = bool]':
33:30: required from here
/usr/include/c++/4.9/condition_variable:97:14: error: '__p' cannot be used as a function
while (!__p())
^
wait() takes a predicate, which is a callable unary function returning bool. wait() uses that predicate like so:
while (!pred()) {
wait(lock);
}
check_func(i,k) is a bool. It's not callable and it's a constant - which defeats the purpose. You're waiting on something that can change. You need to wrap it in something that can be repeatedly callable - like a lambda:
cv.wait(lk, [&]{ return check_func(i,k); });

linux: alarm function doesn't work sometimes?

My code is as follows,The first time ,alarm works very well and handler2() function can work. however, the alarm doesn't work after it implement "doMain()" in the "handler2()".
I mean after the second time print ""In main Pleasae input: \n"", handler2() doesn't wrok anymore.
I don't know why? My code as follows:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
#define MAX_LEN_COMM 64
jmp_buf jumper;
int stop =0; //o is not stop ,otherwise is stop;
void hanlder2();
void doMain();
void handler2()
{
int len_command = 0;
char character;
char commandStr[60];
printf("******************************\n");
printf("In Alarm Pleasae input: \n");
while((character=getchar())!='\n')
{
commandStr[len_command]=character;
len_command++;
}
commandStr[len_command]='\0';
printf("In Alarm input is %s\n",commandStr);
if (strcmp(commandStr,"N")==0||strcmp(commandStr,"n")==0){
printf("In Alarm You put no, we will stop alarm \n");
stop=1;
longjmp(jumper, 2);
}
else if(strcmp(commandStr,"Y")==0||strcmp(commandStr,"y")==0){
printf("In Alarm You put yes, we will continue alarm \n");
signal(SIGALRM, handler2);
alarm(5);
doMain();
}
}
void doMain(){
while(1){
setjmp(jumper);
if(stop==0){
signal(SIGALRM, handler2);
printf("return time %d\n",alarm(5));
}
int len_command = 0;
char character;
char commandStr[60];
printf("In main Pleasae input: \n");
while((character=getchar())!='\n')
{
commandStr[len_command]=character;
len_command++;
}
commandStr[len_command]='\0';
printf("In main input is %s\n",commandStr);
if (strcmp(commandStr,"N")==0||strcmp(commandStr,"n")==0){
printf("In main You put no\n");
}
else if(strcmp(commandStr,"Y")==0||strcmp(commandStr,"y")==0){
printf("In main You put yes\n");
}
}
}
void main()
{
doMain();
}
What you are doing is very wrong.
First, the signature of the handler should be void handler(int sig).
Second, there are very few functions that are safe to use within a handler so you should try to get out of a handler as quickly as possible and definitely not doing console i/o. You are using several unsafe library functions.
Lastly a signal handler is a function. It runs and returns to where your program was interrupted by the signal. During the time a handler runs signals of the same type are not deliverd. By calling doMain() from the handler - which is crazy - the handler never ends. Because it doesn't end you won't see any more alarm signals.

how do i check if execv function faild or succeeded?

i got an assignment to write a simple linux shell ,
this is the code so far :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(int argc,char argv[])
{
char *token;
char command[50];
char tmp[256];
char *arg_command[]={"",0};
int pid,status,flag=0;
char *path = (char*)getenv("PATH");
while(1) // run always
{
printf("\n");
printf(getenv("PWD")); //print current dir
printf(": ");
gets(command);
if (strcmp(command,"exit")==0) //check for exit command
{
printf("bye\n");
break;
}
strcpy(tmp,path);
token = strtok(path,":");
while(token!=NULL)
{
arg_command[0] = command;
pid = fork();
if(pid>=0)
{
printf("\npid is:%d\n",pid);
if (pid==0) // child process is invoked
{
strcat(token,"/");
execv(strcat(token,command),arg_command);
exit(0);
}
else //parent process
{
wait(&status);
if(status==0)
}
}
else
{
printf("fork faild");
}
token = strtok(NULL,":");
}
if (flag == 1)
{
printf("no files or folders match this command\n");
}
strcpy(path,tmp);
}
return 0;
}
my question is how do i know whether execv was able to execute the command or not
because i want to output an error when ever the user entered a wrong command.
i also have a flag but because i cant check execv i cant use it .
Like most Unix/POSIX functions, exec* return an error code (-1) if they fail. errno will then tell you why it failed.
In fact, if they ever return, then something went wrong. Otherwise, the current process is replaced which means no code after is ever execute (exit(0) in your case).

Resources