Write/Read a stream of data (double) using named pipes in C++ - c++

I am trying to develop a little application in C++, within a Linux environment, which does the following:
1) gets a data stream (a series of arrays of doubles) from the output of a 'black-box' and writes it to a pipe. The black-box can be thought as an ADC;
2) reads the data stream from the pipe and feeds it to another application which requires these data as stdin;
Unfortunately, I was not able to find tutorials or examples. The best way I found to realize this is summarized in the following test-bench example:
#include <iostream>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#define FIFO "/tmp/data"
using namespace std;
int main() {
int fd;
int res = mkfifo(FIFO,0777);
float *writer = new float[10];
float *buffer = new float[10];
if( res == 0 ) {
cout<<"FIFO created"<<endl;
int fres = fork();
if( fres == -1 ) {
// throw an error
}
if( fres == 0 )
{
fd = open(FIFO, O_WRONLY);
int idx = 1;
while( idx <= 10) {
for(int i=0; i<10; i++) writer[i]=1*idx;
write(fd, writer, sizeof(writer)*10);
}
close(fd);
}
else
{
fd = open(FIFO, O_RDONLY);
while(1) {
read(fd, buffer, sizeof(buffer)*10);
for(int i=0; i<10; i++) printf("buf: %f",buffer[i]);
cout<<"\n"<<endl;
}
close(fd);
}
}
delete[] writer;
delete[] buffer;
}
The problem is that, by running this example, I do not get a printout of all the 10 arrays I am feeding to the pipe, whereas I keep getting always the first array (filled by 1).
Any suggestion/correction/reference is very welcome to make it work and learn more about the behavior of pipes.
EDIT:
Sorry guys! I found a very trivial error in my code: in the while loop within the writer part, I am not incrementing the index idx......once I correct it, I get the printout of all the arrays.
But now I am facing another problem: when using a lot of large arrays, these are randomly printed out (the whole sequence is not printed); as if the reader part is not able to cope with the speed of the writer. Here is the new sample code:
#include <iostream>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#define FIFO "/tmp/data"
using namespace std;
int main(int argc, char** argv) {
int fd;
int res = mkfifo(FIFO,0777);
int N(1000);
float writer[N];
float buffer[N];
if( res == 0 ) {
cout<<"FIFO created"<<endl;
int fres = fork();
if( fres == -1 ) {
// throw an error
}
if( fres == 0 )
{
fd = open(FIFO, O_WRONLY | O_NONBLOCK);
int idx = 1;
while( idx <= 1000 ) {
for(int i=0; i<N; i++) writer[i]=1*idx;
write(fd, &writer, sizeof(float)*N);
idx++;
}
close(fd);
unlink(FIFO);
}
else
{
fd = open(FIFO, O_RDONLY);
while(1) {
int res = read(fd, &buffer, sizeof(float)*N);
if( res == 0 ) break;
for(int i=0; i<N; i++) printf(" buf: %f",buffer[i]);
cout<<"\n"<<endl;
}
close(fd);
}
}
}
Is there some mechanism to implement in order to make the write() wait until read() is still reading data from the fifo, or am I missing something trivial also in this case?
Thank you for those who have already given answers to the previous version of my question, I have implemented the suggestions.

The arguments to read and write are incorrect. Correct ones:
write(fd, writer, 10 * sizeof *writer);
read(fd, buffer, 10 * sizeof *buffer);
Also, these functions may do partial reads/writes, so that the code needs to check the return values to determine whether the operation must be continued.
Not sure why while( idx <= 10) loop in the writer, this loop never ends. Even on a 5GHz CPU. Same comment for the reader.

Related

C++ KeyboardEmulator

I'm trying to code a KeyBoard Emulator for Linux, first I thought to use python to achieve it, but all the libraries were using X (and I don't want to use it). I decided to code in C++ to write in the keyboard buffer. After a few days of learning C++ and doing some research on Linux and how the input system works, I came up with this:
#include <stdio.h>
#include <fcntl.h>
#include <linux/input.h>
#include <sstream>
#include <unistd.h>
#define EV_PRESSED 1
#define EV_RELEASED 0
int Emulate(char character)
{
printf("Starting the keyboard buffer writer\n");
int fd = 0;
char *device = "/dev/input/event1";
//write to buffer
if( (fd = open(device, O_RDWR)) > 0 )
{
struct input_event event;
printf("The keyboard code is: %d \n", KEY_A);
event.type = EV_KEY;
event.value = EV_PRESSED;
event.code = KEY_A;
write(fd, &event, sizeof(struct input_event));
event.value = EV_RELEASED;
event.code = KEY_A;
write(fd, &event, sizeof(struct input_event));
close(fd);
}
return 0;
}
int main(int argc, char *argv[]){
for(int i=0; i < sizeof(argv[1])/sizeof(int); i++){
Emulate(argv[1][i]);//for each car in the argv 1 call Emulate
}
}
As you can see I'm writing manually KEY_A to press the a key. And I was wondering if there is a function or a way to change a char to the keycodes definded in the file /usr/include/linux/input-event-codes.h.
Thank you for your help !

Possible to retrieve input from user and running another process?

Is it possible to use getline(cin,buffer); at the top of my program, then have a "animated menu" still running below it?
For example (very basic):
#include <iostream>
#include <string>
using namespace std;
int stringLen=0;
string buffer;
getline(cin, buffer);
for (int i = 0; i < kMaxWait;i++)
{
printf("counter waiting for user input %d",i);
if (1 >= buffer.length())
break;
}
Would I have to fork that loop somehow so it would keep counting and display the counter until the user enters something??
One possible answer, given in the comments, is to use threads. But it's not necessary, there's a way to do this without threads.
Make stdin a non-blocking file descriptor.
Wait for stdin to become readable, via poll()/select(), in the meantime do your animation, etc...
Make stdin a blocking file descriptor, again.
Use std::getline().
There are also some ancillary issues to consider, such as the buffering that comes from std::streambuf, so before doing all that, check if there's already something to read from std::cin, first.
This is something I used sometime ago. It's quite rudimentary, but you can get the gist of the process - using poll. It returns true if there is input, and puts it in str, false otherwise. So, you can put this in your loop somewhere, and take action when there is input.
bool polled_input(std::string& str)
{
struct pollfd fd_user_in;
fd_user_in.fd = STDIN_FILENO;
fd_user_in.events = POLLIN;
fd_user_in.revents = 0;
int rv = poll(&fd_user_in, 1, 0);
if (rv == -1) {/* error */}
else if (rv == 0) return false;
else if (fd_user_in.revents & POLLIN)
{
char buffer[MAX_BUFF_SIZE];
int rc = read(STDIN_FILENO, buffer, MAX_BUFF_SIZE-1);
if (rc >= 0)
{
buffer[rc]='\0';
str = std::string(buffer);
return true;
}
else {/* error */}
}
else {/* error */}
}
select is meant for this, multiplexed, blocking I/O. It can be done without a poll I think:
#include <iostream>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **arg)
{
const int time_in_secs = 10;
const int buffer_size = 1024;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
struct timeval tv;
tv.tv_sec = time_in_secs;
tv.tv_usec = 0;
int ret = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &tv);
if (!ret)
{
std::cout << "Timeout\n";
exit(1);
}
char buf[buffer_size];
if (FD_ISSET(STDIN_FILENO, &readfds))
{
int len = read(STDIN_FILENO, buf, buffer_size);
buf[len] = '\0';
}
std::cout << "You typed: " << buf << "\n";
return 0;
}

c++ trying to add Peterson algorithm to avoid race condition in shared memory

I have written two program (program 1 and program 2) to communicate with each other using shared memory. program 1 reads from a file a sentence and pass it after modification to get first letter of each word and its size to the next program ( program 2) . I faced race condition problem. I added Peterson algorithm but once I execute the 2 programs one in foreground and one in background I didn't get any result.
-once i remove the Peterson algorithm my programs work
-i'm working in linux using c++
program 1
#include<iostream>
#include<fstream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
int filesize(){
ifstream input;
input.open("file1.txt");
string temp;
int i = 0;
while(input>>temp){i++;}
input.close();
return i;
}
struct shdata
{
char c;
int n;
int size;
bool flag[2];
int turn;
};
int main(){
ifstream input;
input.open("file1.txt");
int shmid;
key_t key = 8006;
struct shdata *shm;
shmid = shmget(key, sizeof(struct shdata), IPC_CREAT | 0666);
if(shmid < 0){
cout<<"Error .. Can not get memory\n";
exit(0);
}
shm = (struct shdata *)shmat (shmid, NULL, 0);
if(shm <= (struct shdata *)(0))
{
cout<<"Errors.. Can not attach\n";
exit(1);
}
shm->flag[0]=false;
shm->flag[1]=true;
string temp;
while(input>>temp){
shm->flag[0]=true;
shm->turn = 1;
while(shm->flag[1]== true && shm-> turn == 1 );
shm->c=temp[0];
shm->n=temp.size();
shm->size = filesize();
shm->flag[0]=false;
sleep(1);
}
return 0;
}
program 2
#include<iostream>
#include<fstream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
int filesize(){
ifstream input;
input.open("file1.txt");
string temp;
int i = 0;
while(input>>temp){i++;}
input.close();
return i;
}
struct shdata
{
char c;
int n;
int size;
bool flag[2];
int turn;
};
int main(){
int shmid;
key_t key = 8006;
struct shdata *shm;
shmid = shmget(key, sizeof(struct shdata), 0);
if(shmid < 0)
{
cout<<"Error .. Can not get memory\n";
exit(0);
}
shm = (struct shdata *)shmat (shmid,0, 0);
if(shm <= (struct shdata *)(0))
{
cout<<"Error .. Can not attach\n";
exit(1);
}
int c =0;
while(c<shm->size){
shm->flag[1] = true;
shm->turn=0;
while( shm->flag[0]==false && shm->turn == 0);
sleep(1);
for(int i = 0; i < shm->n ;i++)
{
cout<<shm->c;
}
cout<<endl;
shm->flag[1]=false;
c++;
}
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
program 2 never gets into the while(c<shm->size) loop because at that point shm->size is 0. To get around it, progran 1 should initialize shm->size before program 2 reaches that point. This might lead to another race condition because there doesn't seem to be any mechanism to ensure that the shared memory is initialized by program 1 before program 2 starts using it.
It seems to work without the Peterson algorithm because in that case program 1 doesn't wait on the flag and initializes shm->size further down in the loop.
You are using the flag member to synchronize you 2 programs but this cant work because you cant suppose the sequence of read/writes. You must use a small dialect in order to make your two programs starts in the correct order.

How to deactivate input statement after some time?

We know input function or operator (cin, scanf,gets….etc) wait to take input form user & this time has no limit.
Now, I will ask a question & user give the answer, till now there no problem but my problem is “user has a time(may 30 or 40 sec) to give the input, if he fail then input statement will automatically deactivated & execute next statement.”
I think you get my problem. Then please help me in this situation. It will be better if someone give me some really working example code.
I use codebolck 12.11 in windows 7.
An approach for *IX'ish systems (including Cygwin on windows):
You could use alarm() to schedule a SIGALRM, then use read(fileno(stdin), ...).
When the signal arrives read() shall return with -1 and had set errno to EINTR.
Example:
#define _POSIX_SOURCE 1
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void handler_SIGALRM(int signo)
{
signo = 0; /* Get rid of warning "unused parameter ‘signo’" (in a portable way). */
/* Do nothing. */
}
int main()
{
/* Override SIGALRM's default handler, as the default handler might end the program. */
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler_SIGALRM;
if (-1 == sigaction(SIGALRM, &sa, NULL ))
{
perror("sigaction() failed");
exit(EXIT_FAILURE);
}
}
alarm(2); /* Set alarm to occur in two seconds. */
{
char buffer[16] = { 0 };
int result = read(fileno(stdin), buffer, sizeof(buffer) - 1);
if (-1 == result)
{
if (EINTR != errno)
{
perror("read() failed");
exit(EXIT_FAILURE);
}
printf("Game over!\n");
}
else
{
alarm(0); /* Switch of alarm. */
printf("You entered '%s'\n", buffer);
}
}
return EXIT_SUCCESS;
}
Note: In the example above the blocking call to read() would be interupted on any signal arriving. The code to avoid this is left as an execise to the reader ... :-)
Another Method:
You can use POSIX select() function (and some macros FD_ZERO, FD_SET, FD_ISSET) to check which file descriptors (descriptor number 0 i.e. stdin, in this case) are ready to be read in a given time interval. When they are ready, use appropriate function to read the data (scanf() in this case).
This code might help you understand, what I want to say:
#include <sys/select.h>
#include <sys/time.h>
#include <stdio.h>
#define STDIN 0 // Standard Input File Descriptor
int main()
{
fd_set input; // declare a "file descriptor set" to hold all file descriptors you want to check
int fds, ret_val, num; // fds: Number of file descriptors;
struct timeval tv; // structure to store Timeout value in the format used by select() function
unsigned int timeout = 5; // Your timeout period in seconds
tv.tv_sec = timeout;
tv.tv_usec = 0;
fds = STDIN + 1; // Set number of file decriptors to "1 more than the greatest file descriptor"
// Here, we are using only stdin which is equal to 0
FD_ZERO(&input); // Initialize the set with 0
FD_SET(STDIN, &input); // Add STDIN to set
printf("Enter a number within %d secs\n", timeout);
ret_val = select(fds, &input, NULL, NULL, &tv);
// We need to call select only for monitoring the "input file descriptor set"
// Pass rest of them as NULL
if (ret_val == -1) // Some error occured
perror("select()");
else if (ret_val > 0) // At least one of the file descriptor is ready to be read
{
// printf("Data is available now.\n");
if(FD_ISSET(0, &input)) // Check if stdin is set, here its not necessary as we are using STDIN only
// So ret_val>0 means STDIN is raedy to read
{
scanf("%d", &num);
}
}
else
printf("No data within five seconds.\n"); // select returns zero on timeout
return 0;
}
More Help:
select(2)
You can also try using poll() function available in (again a POSIX standard function) as an alternative to select(). See poll() & poll(2)
#include <cstddef>
#include <ctime>
#include <iostream>
#include <conio.h>
bool get_input ( char *buffer, std::size_t size, int timeout )
{
std::time_t start = std::time ( 0 );
std::size_t n = 0;
for ( ; ; ) {
if ( n == 0 && std::difftime ( std::time ( 0 ), start ) >= timeout )
return false;
if ( kbhit() ) {
if ( n == size - 1 )
break;
char ch = (int)getche();
if ( ch == '\r' ) {
buffer[n++] = '\n';
break;
}
else
buffer[n++] = ch;
}
}
buffer[n] = '\0';
return true;
}
int main()
{
char buffer[512] = {0};
if ( !get_input ( buffer, 512, 5 ) ) {
std::cout<<"Input timed out\n";
buffer[0] = '\n';
}
std::cout<<"input: \""<< buffer <<"\"\n";
}

Why Windows C++ muti-threading IOPS is much faster than IOMeter?

I have a SSD and I am trying to use it to simulate my program I/O performance, however, IOPS calculated from my program is much much faster than IOMeter.
My SSD is PLEXTOR PX-128M3S, by IOMeter, its max 512B random read IOPS is around 94k (queue depth is 32).
However my program (32 windows threads) can reach around 500k 512B IOPS, around 5 times of IOMeter! I did data validation but didn't find any error in data fetching. It's because my data fetching in order?
I paste my code belwo (it mainly fetch 512B from file and release it; I did use 4bytes (an int) to validate program logic and didn't find problem), can anybody help me figure out where I am wrong?
Thanks so much in advance!!
#include <stdio.h>
#include <Windows.h>
//Global variables
long completeIOs = 0;
long completeBytes = 0;
int threadCount = 32;
unsigned long long length = 1073741824; //4G test file
int interval = 1024;
int resultArrayLen = 320000;
int *result = new int[resultArrayLen];
//Method declarison
double GetSecs(void); //Calculate out duration
int InitPool(long long,char*,int); //Initialize test data for testing, if successful, return 1; otherwise, return a non 1 value.
int * FileRead(char * path);
unsigned int DataVerification(int*, int sampleItem); //Verify data fetched from pool
int main()
{
int sampleItem = 0x1;
char * fPath = "G:\\workspace\\4G.bin";
unsigned int invalidIO = 0;
if (InitPool(length,fPath,sampleItem)!= 1)
printf("File write err... \n");
//start do random I/Os from initialized file
double start = GetSecs();
int * fetchResult = FileRead(fPath);
double end = GetSecs();
printf("File read IOPS is %.4f per second.. \n",completeIOs/(end - start));
//start data validation, for 4 bytes fetch only
// invalidIO = DataVerification(fetchResult,sampleItem);
// if (invalidIO !=0)
// {
// printf("Total invalid data fetch IOs are %d", invalidIO);
// }
return 0;
}
int InitPool(long long length, char* path, int sample)
{
printf("Start initializing test data ... \n");
FILE * fp = fopen(path,"wb");
if (fp == NULL)
{
printf("file open err... \n");
exit (-1);
}
else //initialize file for testing
{
fseek(fp,0L,SEEK_SET);
for (int i=0; i<length; i++)
{
fwrite(&sample,sizeof(int),1,fp);
}
fclose(fp);
fp = NULL;
printf("Data initialization is complete...\n");
return 1;
}
}
double GetSecs(void)
{
LARGE_INTEGER frequency;
LARGE_INTEGER start;
if(! QueryPerformanceFrequency(&frequency))
printf("QueryPerformanceFrequency Failed\n");
if(! QueryPerformanceCounter(&start))
printf("QueryPerformanceCounter Failed\n");
return ((double)start.QuadPart/(double)frequency.QuadPart);
}
class input
{
public:
char *path;
int starting;
input (int st, char * filePath):starting(st),path(filePath){}
};
//Workers
DWORD WINAPI FileReadThreadEntry(LPVOID lpThreadParameter)
{
input * in = (input*) lpThreadParameter;
char* path = in->path;
FILE * fp = fopen(path,"rb");
int sPos = in->starting;
// int * result = in->r;
if(fp != NULL)
{
fpos_t pos;
for (int i=0; i<resultArrayLen/threadCount;i++)
{
pos = i * interval;
fsetpos(fp,&pos);
//For 512 bytes fetch each time
unsigned char *c =new unsigned char [512];
if (fread(c,512,1,fp) ==1)
{
InterlockedIncrement(&completeIOs);
delete c;
}
//For 4 bytes fetch each time
/*if (fread(&result[sPos + i],sizeof(int),1,fp) ==1)
{
InterlockedIncrement(&completeIOs);
}*/
else
{
printf("file read err...\n");
exit(-1);
}
}
fclose(fp);
fp = NULL;
}
else
{
printf("File open err... \n");
exit(-1);
}
}
int * FileRead(char * p)
{
printf("Starting reading file ... \n");
HANDLE mWorkThread[256]; //max 256 threads
completeIOs = 0;
int slice = int (resultArrayLen/threadCount);
for(int i = 0; i < threadCount; i++)
{
mWorkThread[i] = CreateThread(
NULL,
0,
FileReadThreadEntry,
(LPVOID)(new input(i*slice,p)),
0,
NULL);
}
WaitForMultipleObjects(threadCount, mWorkThread, TRUE, INFINITE);
printf("File read complete... \n");
return result;
}
unsigned int DataVerification(int* result, int sampleItem)
{
unsigned int invalid = 0;
for (int i=0; i< resultArrayLen/interval;i++)
{
if (result[i]!=sampleItem)
{
invalid ++;
continue;
}
}
return invalid;
}
I didn't look in enough detail to be certain, but I didn't see any code there to flush the data to the disk and/or ensure your reads actually came from the disk. That being the case, it appears that what you're measuring is primarily the performance of the operating system's disk caching. While the disk might contribute a little to the performance you're measuring, it's probably only a small contributor, with other factors dominating.
Since the code is apparently written for Windows, you might consider (for one example) opening the file with CreateFile, and passing the FILE_FLAG_NO_BUFFERING flag when you do so. This will (at least mostly) remove the operating system cache from the equation, and force each read or write to deal directly with the disk itself.