mercredi 5 octobre 2016

having trouble re-write my function, trying to use pipe replace pointers to create nodes

Right now my function addnodes is written using a linked list, but I want to recreate it using pipes as pointers. Also I'm not sure on how to declare the int variable that is being passed to the function.

For the C program, it should starts with a single node (with randomly assigned ID). When a new node is created, a new process is forked, pipes created and/or rearranged, and keys properly assigned, by passing data through the network of pipes to get the data items to the correct node.

My program begin with my addnodes function, The addNode routine will know that no nodes have been created first. Then it will fork and the child process will consider itself to be the first node. Each addNode call will send an addNode message through the initial pipe. addNode includes a node ID to be used. The receiving process will either (a) accept the addNode message and insert a new node with the specified ID after itself or (b) pass the message along until the correct process receives it.

For the background, this code chord simulation of distributed hash table (DHT). The program will read an initial set of key values from a text file of random numbers. There's one process for each node in ring. Each node (process) will communicate with its successor node (process) using a pipe between the two processes. So basically it's using pipe instead of linked list.

So far I have two things I want fix in my function:

1) What is the right way to create nodeID that pass through my function? Each node is assigned a random ID number in the range 0-63 when it is created (using the appropriate Linux syscall for random numbers?). For my node id part, I just declared my nodeID. That's definitely wrong, how should I generate a random node ID?

2) How do I use pipe replace the linked list structure, I'm not sure how to make sure a key is stored when the message is accepted. Right I just used the basic pipe concept to use a string to create a message. I'm not sure that's correct way to do it. How do I pass or insert without a linked list in the pipe? I meant using pipes as pointers. Right now my pipe function is not working, I think I'm also missing fork?

Right now I just have a pipe function that works with some pseudo code:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>



typedef struct
{
    int myNode;
    int pipeFromPrevious;
    int pipeToNext;
    struct chennode_s *next;
} chennode_s;



chennode_s* createNewNode(int iNodeId, int iPrevPipe, int iNextPipe)
{
    // allocate a new empty chennode on the heap
    chennode_s* myNewNode = malloc(sizeof(chennode_s));
    // if that was successful, fill it in
    if (myNewNode != NULL)
    {
        myNewNode->myNode           = iNodeId;
        myNewNode->pipeFromPrevious = iPrevPipe;
        myNewNode->pipeToNext       = iNextPipe;
        myNewNode->next             = NULL;
    }
    else
    {
        // detecting errors is a REALLY IMPORTANT debugging aid! :-)
        fprintf (stderr, "dang, cannot create a new node...");
    }
    // now, return the new node to the caller
    return myNewNode;
}


//Then some functions to insert a new node into the list//
//Searched linked list for this
void addNode(int nodeId, chennode_s  **list) {
    if (pipe (mypipe)) {
        fprintf (stderr, "Pipe failed.\n");
        return EXIT_FAILURE;
    }
    // Create a new node struct,
    //find the correct place in the list for it, splice it in and then set pipeFromPrevious in the new node to mypipe[0] and
    // pipeToNext in the *preceding* node to mypipe[1]
    //(unless this is the first node, in which case the main process should keep track of mypipe[1] directly
    newNode = createNewNode(nodeId, mypipe[0], mypipe[1]);
    // if node created OK, deal with it
    if (newNode != NULL)
    {
        // maybe insert newNode into your list here


        // now do the forking stuff for this node...
        pid = fork();
        if (pid == 0) {
            //display message
            close (mypipe[1]);
            node_mainloop();
        } else {
            close (mypipe[0]);
        }
    }
}

void exitRing() {
    //This routine will send an EXITRING message through the initial pipe.
    //The receiving process will pass the message along, then exit.
}

void listData() {
    //This routine will send a LISTDATA message through the initial pipe.
    //The receiving process will list its node ID and the keys that it stores, then pass the message along.
}


void addKey (int key)
{

        //if (I should store this value)
        //{
            //store it;
        //}
        //else
        //{
            //send ADDKEY message to next node in the ring;
        //}

    // This is incomplete because the nodes may need to be rebalanced as part of this


}


// the main program has to be declared like this, and it is easiest to have it here at the bottom, and call to routines above it, so you don't have to forward-declare the routines.
int main(int argc, const char * argv[])
{


    FILE * pFile;
    pFile=fopen ("key.dat","r");
    if (pFile==NULL)
    { // best to ALWAYS use braces, even for a single line, in case you add a line later
        perror ("Error, no keyfile found");
    }
    else
    {
        do  // loop through each line of file...

        {
            // 1. read a line...
            size_t lineLen;
            char* line = fgetln(pFile, &lineLen);
            // 2. parse line into data you need (use "strtol()" perhaps?)
            // 3. then create a node with the data...
            // 4. and add the node to your list etc...
        } while (!eof of file...)
        fclose (pFile);
    }

    return 0;
}




Aucun commentaire:

Enregistrer un commentaire