I'd like to store my serialized data on redis and publish to the channel that i've defined. But it seems that there is a problem on SETting the key value at redis. What do i miss for the solution ?
Thanks in advance.
#include <stdio.h>
#include <assert.h>
#include <signal.h>
#include <stdlib.h>
#include "hiredis.h"
#include "async.h"
#include "macosx.h"
#define PACKETSIZE sizeof(cloudRANMessage)
#define COMMANDSIZE 256
typedef struct cloudRANMessage
{
unsigned int station_id;
unsigned int location_area;
char command[COMMANDSIZE];
}cloudRANMessage;
void printMyMessage(cloudRANMessage *message)
{
printf("%d\n", message->location_area);
printf("%d\n", message->station_id);
printf("%s\n", message->command);
}
void serialize(cloudRANMessage *message, char *data)
{
assert(data != NULL);
memcpy(data, message, sizeof *message);
}
void deserialize(char *data)
{
cloudRANMessage *tempMessage = malloc(sizeof(cloudRANMessage)); // To store deserialized message.
memset(tempMessage, 0, sizeof(cloudRANMessage));
memcpy(tempMessage, data, sizeof(cloudRANMessage));
printMyMessage(tempMessage);
}
void getCallback(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = r;
if (reply == NULL) return;
printf("%s\n", reply->str); // Call deserializaton function for the data retrieval.;
/* Disconnect after receiving the reply to GET */
redisAsyncDisconnect(c);
}
void callbackDeserialize(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = r;
if (reply == NULL) return;
printf("%s\n", reply->str); // Call deserializaton function for the data retrieval.
char *stringReply = reply->element[0]->str;
deserialize(stringReply);
/* Disconnect after receiving the reply to GET */
redisAsyncDisconnect(c);
}
void connectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Error: %s\n", c->errstr);
return;
}
printf("Connected...\n");
}
void disconnectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Error: %s\n", c->errstr);
return;
}
CFRunLoopStop(CFRunLoopGetCurrent());
printf("Disconnected...\n");
}
int main (int argc, char **argv) {
cloudRANMessage *newcloudRANMessage = malloc(sizeof(cloudRANMessage));
newcloudRANMessage->location_area = 7214;
newcloudRANMessage->station_id = 45632;
strcpy(newcloudRANMessage->command, "HANDOVER\0");
char data[PACKETSIZE];
serialize(newcloudRANMessage, data);
signal(SIGPIPE, SIG_IGN);
CFRunLoopRef loop = CFRunLoopGetCurrent();
if( !loop ) {
printf("Error: Cannot get current run loop\n");
return 1;
}
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
if (c->err) {
/* Let *c leak for now... */
printf("Error: %s\n", c->errstr);
return 1;
}
redisMacOSAttach(c, loop);
redisAsyncSetConnectCallback(c,connectCallback);
redisAsyncSetDisconnectCallback(c,disconnectCallback);
redisAsyncCommand(c,getCallback,NULL,"SUBSCRIBE cloudRAN");
// Serialize Data then send to Redis
//redisAsyncCommand(c, getCallback, (char*) "SET", "SET LTEdata %s", data, strlen(data)); // key for our data in this case is LTEdata
redisAsyncCommand(c,NULL, NULL, "SET LTEdata %s", data);
//redisAsyncCommand(c, getCallback,(char*) "GET", "GET LTEdata");
redisAsyncCommand(c, callbackDeserialize,NULL, "GET LTEdata");
// Publish the information to the all subscribers.
redisAsyncCommand(c,NULL, NULL, "PUB cloudRAN %b",data,strlen(data));
CFRunLoopRun();
return 0;
}
In this call to redisAsyncCommand:
redisAsyncCommand(c,NULL, NULL, "SET LTEdata %s", data);
any null bytes appearing in data will terminate the hiredis string interpolation. Since you are binary encoding, this is likely to be truncating your string. Try specifying the length to make it binary-safe:
redisAsyncCommand(c,NULL, NULL, "SET LTEdata %b", data, sizeof(data));
Related
I'm struggling using the mosquitto lib on my RaspberryPI 4 in an non-blocking way.
This is may main method:
#include <stdio.h>
#include <mosquitto.h>
#include "mqtt.h"
#include <string>
int main(int argc, char **argv)
{
printf("Start\n");
MqttConnector * mqtt = new MqttConnector("piClient", "send", "rc", 1883, "localhost", 60);
mqtt->startClient();
printf("MQTT is started\n");
while(1)
{
}
return 0;
}
Important parts of mqtt.cpp
#include "mqtt.h"
#include <stdio.h>
#include <string>
#include <string.h>
#include <mosquitto.h>
MqttConnector::MqttConnector(std::string id, std::string sendTopic, std::string receiveTopic, int port, std::string host, int keepalive)
{
mosquitto_lib_init();
mosqClient = mosquitto_new(id.c_str(), true, this);
if(!mosqClient){
fprintf(stderr, "Error: Out of memory.\n");
}
this->keepalive = keepalive;
this->id = id;
this->host = host;
this->port = port;
this->sendTopic = sendTopic;
this->receiveTopic = receiveTopic;
}
MqttConnector::~MqttConnector()
{
mosquitto_destroy(mosqClient);
mosquitto_lib_cleanup();
}
void MqttConnector::messageCallback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
{
//MqttConnector * mqttInstance = (MqttConnector *) userdata;
if(message->payloadlen){
std::string payloadString = reinterpret_cast<char*>(message->payload);
printf("Message arriving in %s : %s\n", message->topic, payloadString.c_str());
std::string rp = "rp";
if(payloadString == rp)
{
mosquitto_publish(mosq, NULL, "send", strlen("test"), "test", 2, false);
}
}else{
printf("Empty message arriving in %s\n", message->topic);
}
}
void MqttConnector::connectCallback(struct mosquitto *mosq, void *userdata, int result)
{
if(!result){
printf("Connection established\n");
}else{
fprintf(stderr, "Connect failed\n");
}
}
void MqttConnector::logCallback(struct mosquitto *mosq, void *userdata, int level, const char *str)
{
/* Pring all log messages regardless of level. */
printf("%s\n", str);
}
void MqttConnector::publishCallback(struct mosquitto *mosq, void *userdata, int usernumber)
{
printf("Published a message\n");
}
void MqttConnector::startClient()
{
mosquitto_message_callback_set(mosqClient, messageCallback);
mosquitto_log_callback_set(mosqClient, logCallback);
mosquitto_connect_callback_set(mosqClient, connectCallback);
mosquitto_publish_callback_set(mosqClient, publishCallback);
/*
//Connecting without async works! Publish and receiving messages work!
// loop starts by calling loop_forever
if(mosquitto_connect(mosqClient, host.c_str(), port, keepalive)){
fprintf(stderr, "Unable to connect.\n");
}
mosquitto_subscribe(mosqClient, NULL, receiveTopic.c_str(), 2);
mosquitto_loop_forever(mosqClient, 10, 1);
*/
// According to docu we need to call loop_start instead of forever
// not able to publish/receive message with this!
if(mosquitto_connect_async(mosqClient, host.c_str(), port, keepalive)){
fprintf(stderr, "Unable to connect.\n");
}
mosquitto_subscribe(mosqClient, NULL, receiveTopic.c_str(), 2);
mosquitto_loop_start(mosqClient);
}
Connecting to the server with mosquitto_connect and starting the loop with mosquitto_loop_forever is the blocking way. Therefore I only see the first print statement in the main.cpp ('Start'). But with this way, I'm able to publish and receive message with that client.
As soon as I connect with mosquitto_connect_async, I need to start the loop with mosquitto_loop_start as it is mentioned in the documentation. The client connects to the server without an error. And I also see the second print statement from the main.cpp now. But I'm not able to publish oder receive any messages with the mqtt client.
My first guess was that because of the threading, the messages are not printed on the console, but even other clients startet with mosquitto_sub don't receive a message from that c++ client.
Do I need to install something for threading support on the RPI4?
I don't understand why it is not working, because the RPI4 supports multithreading.
Thanks for helping
Currently, I am using a very simple code example which help me working with cross-platform sockets.
Github: Socket c++ cross platform
The problem comes when I was trying to make the http GET request
When I try simple requests, it returns me a correct value, but when I this complex request:
"GET /1.0/stock/aapl/batch?types=quote,news,chart&range=1m&last=10 HTTP/1.0\r\nHost: api.iextrading.com\r\nConnection: close\r\n\r\n"
It returns nothing!
//Main.cpp
#include <string>
#include <ActiveSocket.h>
#define SEND(a,b,c,d) send(a, (const char *)b, (int)c, d)
typedef unsigned char uint8;
int main(int argc, char **argv)
{
CActiveSocket socket; // Instantiate active socket object (defaults to TCP).
char time[50];
memset(&time, 0, 50);
char host[] = "api.iextrading.com";
char message[] = "GET /1.0/stock/aapl/batch?types=quote,news,chart&range=1m&last=10 HTTP/1.0\r\nHost: api.iextrading.com\r\nConnection: close\r\n\r\n";
socket.Initialize();
if (socket.Open(host, 80))
{
if (socket.Send((const uint8 *)message, strlen(message)))
{
socket.Receive(4096);//size of the buffer
socket.Close();
}
}
getchar();
return 1;
}
//CActiveSocket.h
int32 CSimpleSocket::Send(const uint8 *pBuf, size_t bytesToSend)
{
SetSocketError(SocketSuccess);
m_nBytesSent = 0;
switch(m_nSocketType)
{
case CSimpleSocket::SocketTypeTcp:
{
if (IsSocketValid())
{
if ((bytesToSend > 0) && (pBuf != NULL))
{
m_timer.Initialize();
m_timer.SetStartTime();
//---------------------------------------------------------
// Check error condition and attempt to resend if call
// was interrupted by a signal.
//---------------------------------------------------------
do
{
m_nBytesSent = SEND(m_socket, pBuf, bytesToSend, 0);
TranslateSocketError();
} while (GetSocketError() == CSimpleSocket::SocketInterrupted);
m_timer.SetEndTime();
}
}
break;
}
...
}
int32 CSimpleSocket::Receive(int32 nMaxBytes, uint8 * pBuffer )
{
m_nBytesReceived = 0;
if (IsSocketValid() == false)
{
return m_nBytesReceived;
}
uint8 * pWorkBuffer = pBuffer;
if ( pBuffer == NULL )
{
if ((m_pBuffer != NULL) && (nMaxBytes != m_nBufferSize))
{
delete [] m_pBuffer;
m_pBuffer = NULL;
}
if (m_pBuffer == NULL)
{
m_nBufferSize = nMaxBytes;
m_pBuffer = new uint8[nMaxBytes];
}
pWorkBuffer = m_pBuffer;
}
SetSocketError(SocketSuccess);
m_timer.Initialize();
m_timer.SetStartTime();
switch (m_nSocketType)
{
case CSimpleSocket::SocketTypeTcp:
{
do
{
m_nBytesReceived = RECV(m_socket, (pWorkBuffer +m_nBytesReceived), nMaxBytes, m_nFlags);
TranslateSocketError();
} while ((GetSocketError() == CSimpleSocket::SocketInterrupted));
break;
}
...
}
I write a C++ dome of tcp server with the libuv. When I check the cpu performance, I found the dome is a single thread running, how can I implement it with multi-thread?
Currently, the dome can hanlde 100,000+ tcp request per second, it can only eat 1 CPU.
Code:
#include <iostream>
#include <atomic>
#include "uv.h"
#include <thread>
#include <mutex>
#include <map>
using namespace std;
auto loop = uv_default_loop();
struct sockaddr_in addr;
typedef struct {
uv_write_t req;
uv_buf_t buf;
} write_req_t;
typedef struct {
uv_stream_t* client;
uv_alloc_cb alloc_cb;
uv_read_cb read_cb;
} begin_read_req;
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = (char*)malloc(suggested_size);
buf->len = suggested_size;
}
void free_write_req(uv_write_t *req) {
write_req_t *wr = (write_req_t*)req;
free(wr->buf.base);
free(wr);
}
void echo_write(uv_write_t *req, int status) {
if (status) {
fprintf(stderr, "Write error %s\n", uv_strerror(status));
}
free_write_req(req);
}
void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
if (nread > 0) {
auto req = (write_req_t*)malloc(sizeof(write_req_t));
auto *aaa = (char*)malloc(5);
aaa[0] = '+';
aaa[1] = 'O';
aaa[2] = 'K';
aaa[3] = '\r';
aaa[4] = '\n';
req->buf = uv_buf_init(aaa, 5);
uv_write((uv_write_t*)req, client, &req->buf, 1, echo_write);
}
if (nread < 0) {
if (nread != UV_EOF)
fprintf(stderr, "Read error %s\n", uv_err_name(static_cast<unsigned int>(nread)));
uv_close((uv_handle_t*)client, nullptr);
}
free(buf->base);
}
void acceptClientRead(uv_work_t *req) {
begin_read_req *data = (begin_read_req *)req->data;
uv_read_start(data->client, data->alloc_cb, data->read_cb);
}
void on_new_connection(uv_stream_t *server, int status) {
if (status < 0) {
cout << "New connection error:" << uv_strerror(status);
return;
}
uv_tcp_t *client = (uv_tcp_t *)malloc(sizeof(uv_tcp_t));
uv_tcp_init(loop, client);
uv_work_t *req = (uv_work_t *)malloc(sizeof(uv_work_t));
begin_read_req *read_req = (begin_read_req *)malloc(sizeof(begin_read_req));
read_req->client = (uv_stream_t *)client;
read_req->read_cb = echo_read;
read_req->alloc_cb = alloc_buffer;
req->data = read_req;
if (uv_accept(server, (uv_stream_t *)client) == 0) {
uv_read_start((uv_stream_t *)client, alloc_buffer, echo_read);
// uv_queue_work(workloop[0], req, acceptClientRead, nullptr);
}
else {
uv_close((uv_handle_t *)client, nullptr);
}
}
void timer_callback(uv_timer_t* handle) {
cout << std::this_thread::get_id() << "---------" << "hello" << endl;
}
int main() {
uv_tcp_t server{};
uv_tcp_init(loop, &server);
uv_ip4_addr("0.0.0.0", 8790, &addr);
uv_tcp_bind(&server, (const struct sockaddr *) &addr, 0);
uv_listen((uv_stream_t *)&server, 511, on_new_connection);
uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
Of course, I can make the write step asynchronous in the method "echo_read", but I didn't do anything before the write, can I make the demo multi-thread in another way to improve the throughput?
I am using HiRedis with a c/c++ program and have written some tests to verify that subscriptions work (I based my solution on this comment).
However, currently I can only publish by manually typing something like publish foo "abcd" into the redis-cli terminal. This works as per the linked comment, but I'd like to publish from my c++ program. How can I do this?
I have tried this command:
redisAsyncCommand(c, SubCallback, (char*)"command", "publish foo \"abcd\"");
But that results in this runtime error:
Error: ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in this context
How can I publish data from within HiRedis?
Once a connection context has subscribed, it can't be used to PUBLISH. You must create a new connection.
from https://github.com/redis/hiredis in hiredis/examples/example-libevent.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <hiredis.h>
#include <async.h>
#include <adapters/libevent.h>
void getCallback(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = r;
if (reply == NULL) return;
printf("argv[%s]: %s\n", (char*)privdata, reply->str);
/* Disconnect after receiving the reply to GET */
redisAsyncDisconnect(c);
}
void connectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Error: %s\n", c->errstr);
return;
}
printf("Connected...\n");
}
void disconnectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Error: %s\n", c->errstr);
return;
}
printf("Disconnected...\n");
}
int main (int argc, char **argv) {
signal(SIGPIPE, SIG_IGN);
struct event_base *base = event_base_new();
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
if (c->err) {
/* Let *c leak for now... */
printf("Error: %s\n", c->errstr);
return 1;
}
redisLibeventAttach(c,base);
redisAsyncSetConnectCallback(c,connectCallback);
redisAsyncSetDisconnectCallback(c,disconnectCallback);
redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
event_base_dispatch(base);
return 0;
}
In my assignment I have to fork processes to simulate a distributed operating system with process allocating using Heuristic Algorithm On Linux using IPC.
Now I fork n children and then make them simulate the algorithm, that's not the problem though the problem is in the message queue connections between all of them
There is 2 message queues UP and DOWN they are both not working atm.
Every time I try to send something over any of these queues they are received at the other side as garbage.
So, I use this struct and those methods for dealing with message queue
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
struct msgbuff
{
long mtype;
char mtext[70];
};
void Send(key_t msgqid,char* S,long pid)
{
int send_val;
struct msgbuff message;
message.mtype = pid; /* arbitrary value */
strcpy(message.mtext,S);
cout<<"Message is "<<message.mtext<<endl;
//strcpy(message.mtext, str);
cout<<getpid()<<" Entering Send process"<<endl;
send_val = msgsnd (msgqid, &message, sizeof(message), IPC_NOWAIT);
if(send_val == -1)
perror("Error in send");
}
char* Recieve(key_t msgqid,bool nowait)
{
int rec_val;
struct msgbuff message;
cout<<getpid()<<" Entering Receive process"<<endl;
/* receive all types of messages */
if(nowait)
rec_val = msgrcv(msgqid, &message, sizeof(message), getpid(), IPC_NOWAIT);
else rec_val = msgrcv(msgqid, &message, sizeof(message), getpid(), !IPC_NOWAIT);
if(rec_val == -1){
// perror("Error in receive");
return "none";
}
return message.mtext;
}
Then I use them at every child like so
DOWN = msgget(200, IPC_CREAT|0644);
UP = msgget(201,IPC_CREAT|0644);
And
while(1)
{
int countfail =0;
char* ask =Recieve(DOWN,true); //nowait
string asks(ask);
cout<<getpid()<<" ask= "<<asks<<endl; //This here prints either garbage (symbols and other random characters) or "none"
if(strcmp(ask,"none")!=0)
{
///////Logic for the algorithm
cout<<"*********"<<getpid()<<" In ASK "<<endl;
stringstream ss1;
ss1.str(ask);
int senderpid=0,processSize=0;
ss1>>processSize>>senderpid;
char* processRecMessage = new char[70];
///setting up what will be sent to other process
if(count+ processSize <= load)
{
count+=processSize;
strcpy(processRecMessage,"Taken");
}
else
{
strcpy(processRecMessage,"Not Taken");
}
//Another Garbage here
Send(UP,processRecMessage,senderpid);
}
else{
int nextProcess = (rand()%3) +1;
if(count + nextProcess <=load)
{
count +=nextProcess;
}
else{
for(int k = 0;k<3;k++)
{
int selectedChild = rand()%n;
cout<<getpid()<<" Selected Child no "<<selectedChild+1<<" PID="<<children[selectedChild]<<endl;
char* x = new char[70];
stringstream ss;
ss<<nextProcess;
ss<<" "<<getpid();
strcpy(x,ss.str().c_str());// x= "nextProcess pid"
cout<<x<<endl;
//// sending here also recieves garbage
Send (DOWN , x,children[selectedChild]);
//// receiving garbage
x= Recieve(UP,false);
cout<<getpid()<<" UP Value = "<<x<<endl;
if (strcmp(x,"Taken")==0){
cout<<"Process sent from "<<getpid()<<" to "<<children[selectedChild]<<endl;
break;
}
else
{
countfail++;
printf("TRAIL #%d failed\n",countfail);
}
}
if(countfail==3)
{
cout<<"Algorithm failed to allocate process.\n";
cout<<"Terminating Process "<<getpid()<<endl;
break;
}
}
}
}
So If anyone could help me with this I would be grateful
p.s.:
I delete all message queues after each fail run of the program so each time they start anew but still no use.
edit:
Adding the full code
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <math.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <string.h>
#include <map>
#include <sstream>
#include <ctime>
using namespace std;
struct msgbuff
{
long mtype;
char mtext[70];
};
void Send(key_t msgqid,char* S,long pid)
{
int send_val;
struct msgbuff message;
message.mtype = pid; /* arbitrary value */
strcpy(message.mtext,S);
cout<<"Message is "<<message.mtext<<endl;
//strcpy(message.mtext, str);
cout<<getpid()<<" Entering Send process"<<endl;
send_val = msgsnd (msgqid, &message, sizeof(message), IPC_NOWAIT);
if(send_val == -1)
perror("Errror in send");
}
char* Recieve(key_t msgqid,bool nowait)
{
int rec_val;
struct msgbuff message;
cout<<getpid()<<" Entering Receive process"<<endl;
/* receive all types of messages */
if(nowait)
rec_val = msgrcv(msgqid, &message, sizeof(message), getpid(), IPC_NOWAIT);
else rec_val = msgrcv(msgqid, &message, sizeof(message), getpid(), !IPC_NOWAIT);
if(rec_val == -1){
// perror("Error in receive");
return "none";
}
return message.mtext;
}
int main()
{
int n ;
pid_t pid;
key_t DOWN,UP;
DOWN = msgget(200, IPC_CREAT|0644);//Creates new identifier
UP = msgget(201,IPC_CREAT|0644);
int shmid;
shmid = shmget(50, 393216, IPC_CREAT|0644);
void *shmaddr;
shmaddr = shmat(shmid, (void *)0, 0);
printf("DOWN = %d\n", DOWN);
printf("UP = %d\n", UP);
cout<<"Please enter the number of machines "<<endl;
cin>>n;
int* children = new int[n];
string pids;
stringstream ss4;
ss4<<n;
string number = ss4.str();
pids+=number;
pids+=" ";
for (int i=0;i<n;i++)
{
pid = fork();
children[i]=pid;
stringstream ss3;
ss3<<pid;
string pidstr=ss3.str();
pids+=pidstr;
pids+=" ";
if (pid==0)
break;
}
if (pid==-1)
cout<<"Error in fork" <<endl;
else if (pid==0) // child
{
sleep(1);
DOWN = msgget(200, IPC_CREAT|0644);
UP = msgget(201,IPC_CREAT|0644);
//cout<<"Entering child process"<<endl;
shmid = shmget(50, 393216, IPC_CREAT|0644);
shmaddr = shmat(shmid, (void *)0, 0);
char* pidsrec = new char[100];
strcpy(pidsrec,(char*) shmaddr);
stringstream sss;
string spid(pidsrec);
sss.str(spid);
sss>>n;
children = new int[n];
for(int i =0;i<n;i++)
{
sss>>children[i];
//cout<<getpid()<<"Child #"<<i<<" = "<<children[i]<<endl;
}
srand(getpid());
int load = (rand()%10) +1; // load of operating on this system from 1-10
int count=0;
while(1)
{
int countfail =0;
char* ask =Recieve(DOWN,true); //nowait
string asks(ask);
cout<<getpid()<<" ask= "<<asks<<endl;
if(strcmp(ask,"none")!=0)
{
cout<<"*********"<<getpid()<<" In ASK "<<endl;
stringstream ss1;
ss1.str(ask);
int senderpid=0,processSize=0;
ss1>>processSize>>senderpid;
char* processRecMessage = new char[70];
if(count+ processSize <= load)
{
count+=processSize;
strcpy(processRecMessage,"Taken");
}
else
{
strcpy(processRecMessage,"Not Taken");
}
Send(UP,processRecMessage,senderpid);
}
else{
int nextProcess = (rand()%3) +1;
if(count + nextProcess <=load)
{
count +=nextProcess;
}
else{
for(int k = 0;k<3;k++)
{
int selectedChild = rand()%n;
cout<<getpid()<<" Selected Child no "<<selectedChild+1<<" PID="<<children[selectedChild]<<endl;
char* x = new char[70];
stringstream ss;
ss<<nextProcess;
ss<<" "<<getpid();
strcpy(x,ss.str().c_str());// x= "nextProcess pid"
cout<<x<<endl;
Send (DOWN , x,children[selectedChild]);
x= Recieve(UP,false);
cout<<getpid()<<" UP Value = "<<x<<endl;
if (strcmp(x,"Taken")==0){
cout<<"Process sent from "<<getpid()<<" to "<<children[selectedChild]<<endl;
break;
}
else
{
countfail++;
printf("TRAIL #%d failed\n",countfail);
}
}
if(countfail==3)
{
cout<<"Algorithm failed to allocate process.\n";
cout<<"Terminating Process "<<getpid()<<endl;
break;
}
}
}
}
}
else //parent
{
strcpy((char*) shmaddr,pids.c_str());
}
cout<<getpid()<<" GOODBYE"<<endl;
return 0;
}
I try it with any number of processes and there is always garbage received at the receive end of the message queue
In your Receive function, when you do
return message.mtext;
you are returning a pointer to data allocated locally on the stack. This area of the stack will not be valid after the function returns, and hence the dereferencing the pointer will cause undefined behavior. Also, if you use this pointer after calling another function, that area of the stack will most likely have been overwritten by the other function.
Since you're using C++, why not return std::string? It will solve this problem.