[an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] (none) [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] (none) [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive]
 
[an error occurred while processing this directive] [an error occurred while processing this directive]
Skåne Sjælland Linux User Group - http://www.sslug.dk Home   Subscribe   Mail Archive   Forum   Calendar   Search
MhonArc Date: [Date Prev] [Date Index] [Date Next]   Thread: [Date Prev] [Thread Index] [Date Next]   MhonArc
 

Re: [PROGRAMMERING] Hvordan ? Et program skal sende beskeder til N andre.



Hvis du skal have en high performance løsning, så er det jo nok
shared memory der er hurtigst. Jeg har lavet et lille eksempel
nedenfor, hvor en process distribuerer noget data til 4 child
processer via shared memory.
Jeg antager dog, at du vil have forskellige processer, fordi de
så ikke kan overskrive hinandens memory og den slags. Så skal
man i hvert fald sætte andre rettigheder på den sharede memory
end jeg har gjort (write for parent, read for børn) og køre
signaleringen via en anden methode, f.eks. normale UNIX signaler
til process grupper. Signaleringen i eksemplet kan måske være
uhensigtsmæssig, fordi man bruger usleep og polling.
Man kan skrive en generisk proxy, der tager inputtet fra parent
processen og forwarder disse data til en anden maskine, hvis man
har brug for det.

Men løsningen er måske for high tech til dit problem?

Hilsen, Hans-Christian Stadler

PS: Nedenstående output hjelper måske på forståelsen af eksemplet
sslug@sslug:~/Projects/C++/test$ g++ -Wall -o shm_test shm_test.cxx
sslug@sslug:~/Projects/C++/test$ echo helloooooooooooooooooooooooooooooooo | ./shm_test
parent: 31 bytes read: hellooooooooooooooooooooooooooo
child 0: hellooooooooooooooooooooooooooo
child 1: hellooooooooooooooooooooooooooo
child 2: hellooooooooooooooooooooooooooo
child 3: hellooooooooooooooooooooooooooo
parent: 6 bytes read: ooooo

child 0: ooooo

child 1: ooooo

child 2: ooooo

child 3: ooooo

-------------------------------------------------
#include <sys/shm.h>
#include <csignal>
#include <cstring>
#include <iostream>

using namespace std;

const unsigned int num_readers = 4;

typedef struct {
  volatile sig_atomic_t reader[num_readers];
  volatile sig_atomic_t writer;
} pos_t;

const int data_size = 32;
const int shm_size =  sizeof(pos_t) + data_size;

typedef struct {
  pos_t pos;
  volatile char data[data_size];
} shared_t;

static shared_t *sh;

void reset_pos (void)
{
  unsigned int i;
  sh->pos.writer = 0;
  for (i=0; i<num_readers; i++)
    sh->pos.reader[i] = 0;
}

void do_child (unsigned int child_no)
{
  do {  // loop around, reading and printing what parent writes
    while (sh->pos.writer <= sh->pos.reader[child_no])
      usleep(100000);

    cout << "child " << child_no << ": " << (char *)sh->data << endl;

    sh->pos.reader[child_no] = sh->pos.writer; // reset event for parent
  } while(1);
}

void do_parent (void)
{
  do { // loop around, reading and distributing std input
    int sz = read(STDIN_FILENO, (void *)sh->data, data_size-1);
    if (sz == 0)
      return;
    else if (sz == -1)
      cerr << "read from stdin failed: " << strerror(errno) << endl, exit(1);

    sh->data[sz] = 0;
    cout << "parent: " << sz << " bytes read: " << (char *)sh->data << endl;

    sh->pos.writer = sz; // start event for children

    usleep(100000); // let children read the data
    unsigned int i;
    for (i=0; i<num_readers; i++) {
      if (sh->pos.reader[i] != sz)
 usleep(100000), i=0;
    }

    reset_pos();
  } while(1);
}

int main (int argc, char *argv[])
{
  int shm_id;
  void *shm_addr;
  unsigned int i;
  pid_t pid = getpid();

  if ((shm_id = shmget(IPC_PRIVATE, shm_size, IPC_CREAT|0777)) == -1)
    cerr << "shmget failed: " << strerror(errno) << endl, exit(1);

  if ((shm_addr = shmat(shm_id, (const void *)0, 0)) == (void *)-1)
    cerr << "shmat failed: " << strerror(errno) << endl, exit(1);
  
  sh = (shared_t *)shm_addr; // set sh to beginning of shared mem
  reset_pos();

  for (i=0; (i<num_readers) && fork(); i++);

  if (getpid() == pid) { // parent
    if (i < num_readers) // die
      cerr << "some fork failed: " << strerror(errno) << endl, exit(1);
    do_parent();
  } else // some child
    do_child(i);

  return 0;
}



 
Home   Subscribe   Mail Archive   Index   Calendar   Search

 
 
Questions about the web-pages to <www_admin>. Last modified 2005-08-10, 22:44 CEST [an error occurred while processing this directive]
This page is maintained by [an error occurred while processing this directive]MHonArc [an error occurred while processing this directive] # [an error occurred while processing this directive] *