I'm using Ragel to parse a string in C++. I need to be able to pause parsing for some indefinite time and then resume parsing where I left off.
Right now I'm trying to do this by putting an fbreak at the end of a finishing action. This seems to work fine, relinquishing control back to the parent program. However, I'm not sure how to resume parsing. I thought that just calling the code generated by %write exec would be enough, but this doesn't seem to be the case. When it gets back into parsing, the reference to the original string seems to be wrong/lost.
Not sure if I'm doing something wrong in C++ here (it's not my native tongue) or if I'm taking the wrong approach with Ragel.
Here's my start and resume code:
const char *p;
const char *pe;
void start()
{
int len = theString.length();
char chars[len+1];
theString.toCharArray(chars, len+1);
p = chars;
pe = chars + len;
resume();
}
void resume() {
%% write exec;
}
The first time I call start(), my statemachine eventually fbreaks out, and then i call resume() to (hopefully) continue parsing.
Any pointers on what I might be doing wrong?
Looks like it was some sort of dangling pointer problem. Moving the initialization of theString elsewhere seems to have fixed the problem. So basically, I still suck at C.
Related
This question already has an answer here:
How can I run 3 QProcess in background using the same executable
(1 answer)
Closed 5 years ago.
I'm programming with Qt (c++) but my issue is universal in programming (most probably).
To simplify things, the function GetInput(string input) continuously scans for new input.
Depending on the input, the program exits or calls a recursive function.
The problem is, the RecursiveFunc() function blocks the GetInput() function, thus making it impossible to get further input (making it impossible to exit). Basically, the RecursiveFunc() function will call itself over and over, so the GetInput function never returns, making it impossible to get any more input.
My Question: How does a function call a recursive function BUT STILL continuously run and return WHILE the recursion is running.
//needs to constantly scan for input
void GetInput(string input)
{
if (input == "exit")
{
//terminate program
//this point is never reached after calling RecursiveFunc()
}
else if (input == "program1")
{
//Code executions gets stuck here because of recursion
RecursiveFunc();
int i = 0; //this statement is never reached, for example
}
}
void RecursiveFunc()
{
//update some values
//do some more things
//sleep a little, then call the fuction again
RecursiveFunc()
}
I'm thinking, something similiar to a fire-and-forget mechanism would be needed, but I can't quite figure it out. I could probably use threads, but I'm trying to avoid that (as the program should stay as simple as possible). As stated, I'm using Qt. So, what options do I have? What's the best solution in terms of simplicity?
Threads, co-routines, message loops with timers.
Qt has a message loop; change architecture to use that is simplest.
Co-routines lack language support, but there are myriads of implementations people have hacked together.
Threading is complex to get right, but keeps each code looking mostly linear.
Conclusion: Rewrite your code to be message loop based. Instead of recursive and sleeping, post a delayed message to do work later.
All right,
I found a way to achieve what I wanted without any fancy message loops and without rewriting my whole code. Instead of calling RecursiveFunc() recursively, I'm now calling GetInput() recursively (with qobject meta calls).
Simplified, this is my hackerishy solution:
//needs to constantly scan for input
void GetInput(string input)
{
if (input == "x")
{
//terminate program
}
else if (input == "program1")
{
RecursiveFunc();
//sleep a little
GetInput(""); //calls GetInput() recursively
}
}
void RecursiveFunc()
{
//update some values
//do some more things
}
I'm not sure if this is a very good practice, but it works for now.
I am relearning C++. I was quite a noob before but I am going over the basics again and hopefully going further. My main question is, at the end of the main loop, is there a way to call the function again instead of ending the programme by returning 0. So something along the line of:
........
return main;
}
The standard C++ says...
5.2.2.9 Recursive calls are permitted, except to the function named main
"The Standard" at https://isocpp.org/std/the-standard
You could certainly do something like this:
int main()
{
while(1==1) /* (1==1) is always true. */
{
/* Do the hokey pokey, turn yourself around, and do whatever else you feel like doing. */
}
/* The program will never reach this point unless you explicitly break out of the loop. */
return 0;
}
This will result in a program that just repeats over and over again until you kill it. This is, of course, bad style, but it will work if you just need to get something up and running quickly.
As Trevor Hickey mentions, you could call break from within the loop and break out.
I am developing a Qt interface for a 3D printer. When I cilck the Print button (the printer starts printing) the interface crashes. I am using this code:
*future= QtConcurrent::run(Imprimir,filename.toUtf8().data());
What can I use to solve it?? What types of threads can I use????
I need to use the interface while the printer is printing (it may take several minutes).
Thank you for advance.
Edit:
Imprimir function:
int Imprimir(char *fich)
{
char *aux = new char;
FILE *f;
f=fopen(fich, "r");
while(!feof(f)){
fgets(aux, 200, f);
Enviar(aux);
while(!seguir_imprimiendo);
}
Sleep(7000);
return 0;
}
It's making life harder than necessary by not using QFile. When you use QFile, you don't have to deal with silly things like passing C-string filenames around. You're likely to do it wrong, since who's to guarantee that the platform expects them to be encoded in UTF-8. The whole point of Qt is that it helps you avoid such issues. They are taken care of, the code is tested on multiple platforms to ensure that the behavior is correct in each case.
By not using QByteArray and QFile, you're liable to commit silly mistakes like your C-classic bug of allocating a single character buffer and then pretending that it's 200 characters long.
I see no reason to sleep in that method. It also makes no sense to wait for the continue flag seguir_imprimiendo to change, since Enviar runs in the same thread. It should block until the data is sent.
I presume that you've made Enviar run its code through QtConcurrent::run, too. This is unnecessary and leads to a deadlock. Think of what happens if a free thread can never be available while Imprimir is running. It's valid for the pool Imprimir runs on to be limited to just one thread. You can't simply pretend that it can't happen.
bool Imprimir(const QString & fileName)
{
QFile src(fileName);
if (! src.open(QIODevice::ReadOnly)) return false;
QByteArray chunk;
do {
chunk.resize(4096);
qint64 read = src.read(chunk.data(), chunk.size());
if (read < 0) return false;
if (read == 0) break; //we're done
chunk.resize(read);
if (!Enviar(chunk)) return false;
} while (! src.atEnd());
return true;
}
bool Enviar(const QByteArray & data)
{
...
return true; // if successful
}
Assuming there's no problem with Imprimir, the issue is probably with filename.toUtf8().data(). The data pointer you get from this function is only valid while filename is in-scope. When filename goes out of scope, the data may be deleted and any code accessing the data will crash.
You should change the Imprimir function to accept a QString parameter instead of char* to be safe.
If you can't change the Imprimir function (because it's in another library, for example), then you will have to wrap it in your own function which accepts a QString. If you're using C++11, you can use a lambda expression to do the job:
QtConcurrent::run([](QString filename) {
Imprimir(filename.toUtf8().data());
}, filename);
If not, you will have to write a separate ImprimirWrapper(QString filename) function and invoke it using QtConcurrent::run.
I have a program that processes neural spike data that is broadcast in UDP packets on a local network.
My current program has two threads a UI thread and a worker thread. The worker thread simply listens for data packets, parses them and makes them available to the UI thread for display and processing. My current implementation works just fine. However for a variety of reasons I'm trying to re-write the program in C++ using an Object Oriented approach.
The current working program initialized the 2nd thread with:
pthread_t netThread;
net = NetCom::initUdpRx(host,port);
pthread_create(&netThread, NULL, getNetSpike, (void *)NULL);
Here is the getNetSpike function that is called by the new thread:
void *getNetSpike(void *ptr){
while(true)
{
spike_net_t s;
NetCom::rxSpike(net, &s);
spikeBuff[writeIdx] = s;
writeIdx = incrementIdx(writeIdx);
nSpikes+=1;
totalSpikesRead++;
}
}
Now in my new OO version of the program I setup the 2nd thread in much the same way:
void SpikePlot::initNetworkRxThread(){
pthread_t netThread;
net = NetCom::initUdpRx(host,port);
pthread_create(&netThread, NULL, networkThreadFunc, this);
}
However, because pthead_create takes a pointer to a void function and not a pointer to an object's member method I needed to create this simple function that wraps the SpikePlot.getNetworSpikePacket() method
void *networkThreadFunc(void *ptr){
SpikePlot *sp = reinterpret_cast<SpikePlot *>(ptr);
while(true)
{
sp->getNetworkSpikePacket();
}
}
Which then calls the getNetworkSpikePacket() method:
void SpikePlot::getNetworkSpikePacket(){
spike_net_t s;
NetCom::rxSpike(net, &s);
spikeBuff[writeIdx] = s; // <--- SegFault/BusError occurs on this line
writeIdx = incrementIdx(writeIdx);
nSpikes+=1;
totalSpikesRead++;
}
The code for the two implementations is nearly identical but the 2nd implementation (OO version) crashes with a SegFault or BusError after the first packet that is read. Using printf I've narrowed down which line is causing the error:
spikeBuff[writeIdx] = s;
and for the life of me I can't figure out why its causing my program to crash.
What am I doing wrong here?
Update:
I define spikeBuff as a private member of the class:
class SpikePlot{
private:
static int const MAX_SPIKE_BUFF_SIZE = 50;
spike_net_t spikeBuff[MAX_SPIKE_BUFF_SIZE];
....
}
Then in the SpikePlot constructor I call:
bzero(&spikeBuff, sizeof(spikeBuff));
and set:
writeIdx =0;
Update 2: Ok something really weird is going on with my index variables. To test their sanity I changed getNetworkSpikePacket to:
void TetrodePlot::getNetworkSpikePacket(){
printf("Before:writeIdx:%d nspikes:%d totSpike:%d\n", writeIdx, nSpikes, totalSpikesRead);
spike_net_t s;
NetCom::rxSpike(net, &s);
// spikeBuff[writeIdx] = s;
writeIdx++;// = incrementIdx(writeIdx);
// if (writeIdx>=MAX_SPIKE_BUFF_SIZE)
// writeIdx = 0;
nSpikes += 1;
totalSpikesRead += 1;
printf("After:writeIdx:%d nspikes:%d totSpike:%d\n\n", writeIdx, nSpikes, totalSpikesRead);
}
And I get the following output to the console:
Before:writeIdx:0 nspikes:0 totSpike:0
After:writeIdx:1 nspikes:32763 totSpike:2053729378
Before:writeIdx:1 nspikes:32763 totSpike:2053729378
After:writeIdx:1 nspikes:0 totSpike:1
Before:writeIdx:1 nspikes:0 totSpike:1
After:writeIdx:32768 nspikes:32768 totSpike:260289889
Before:writeIdx:32768 nspikes:32768 totSpike:260289889
After:writeIdx:32768 nspikes:32768 totSpike:260289890
This method is the only method where I update their values (besides the constructor where I set them to 0). All other uses of these variables are read only.
I'm going to go on a limb here and say all your problems are caused by the zeroing out of the spike_net_t array.
In C++ you must not zero out objects with non-[insert word for 'struct-like' here] members. i.e. if you have an object that contains a complex object (a std string, a vector, etc. etc.) you cannot zero it out, as this destroys the initialization of the object done in the constructor.
This may be wrong but....
You seemed to move the wait loop logic out of the method and into the static wrapper. With nothing holding the worker thread open, perhaps that thread terminates after the first time you wait for a UDP packet, so second time around, sp in the static method now points to an instance that has left scope and been destructed?
Can you try to assert(sp) in the wrapper before trying to call its getNetworkSpikePacket()?
It looks like your reinterpret_cast might be causing some problems. When you call pthread_create, you are passing in "this" which is a SpikePlot*, but inside networkThreadFunc, you are casting it to a TetrodePlot*.
Are SpikePlot and TetrodePlot related? This isn't called out in what you've posted.
If you are allocating the spikeBuff array anywhere then make sure you are allocating sufficient storage so writeIdx is not an out-of-bounds index.
I'd also check that initNetworkRxThread is being called on an allocated instance of spikePlot object (and not on just a declared pointer).
I am having some problem related to C/C++:
Suppose I have some class
class Demo
{
int constant;
public:
void setConstant(int value)
{
constant=value;
}
void submitTask()
{
// need to make a call to C-based runtime system to submit a
// task which will be executed "asynchronously"
submitTask((void *)&constant);
}
};
// runtime system will call this method when task will be executed
void func(void *arg)
{
int constant= *((int *)arg);
// Read this constant value but don't modify here....
}
Now in my application, I do something like this:
int main()
{
...
Demo objDemo;
for(...)
{
objDemo.setConstant(<somevalue>);
objDemo.submitTask();
}
...
}
Now, hopefully you see the problem as tasks should read the value set immediately before a asynchronous call . As task calls are asynchronous so a task can read wrong value and sometimes results in unexpected behavior.
I don't want to enforce synchronous task execution just because of this constraint. The number of tasks created are not known in advance. I just need to pass this simple integer constant in an elegant way that will work with asynchronous. Obviously I cannot change the runtime behavior (mean that signature of this method void func(void *arg) is fixed).
Thanks in advance.
If you don't want to wait for the C code to finish before you make the next call then you can't reuse the same memory location over and over. Instead, create an array and then pass those locations. For this code, I'm going to assume that the number of times the for loop will run is n. This doesn't have to be known until it's time for the for loop to run.
int* values = new int[n];
for(int i=0;i<n;i++) {
values[i] = <somevalue>;
submitTask((void*)&values[i]);
}
At some later point when you're sure it's all done, then call
delete[] values;
Or, alternately, instead of an array of ints, create an array of Demo objects.
Demo demo[] = new Demo[n];
for(int i=0;i<n;i++) {
demo[i].setConstant(<somevalue>);
demo[i].submitTask();
}
But the first makes more sense to me as the Demo object doesn't really seem to do anything worthwhile. But you may have left out methods and members not relevant to the question, so that could change which option is best. Regardless, the point is that you need separate memory locations for separate values if you don't know when they're going to get used and don't want to wait.