Finden Sie heraus, wie viele Prozesse auf dem Namen Semaphore wartenLinux

Linux verstehen
Anonymous
 Finden Sie heraus, wie viele Prozesse auf dem Namen Semaphore warten

Post by Anonymous »

Ich habe hier ein Spielzeugprogramm (http://stackoverflow.com/a/16400833) gefunden, um die Namen Semaphores zu lesen. Ich habe es etwas geändert und das genannte Semaphor in jedem untergeordneten Thread statt im übergeordneten Programm geöffnet. Nach dem sem_wait () habe ich einen sem_getValue (), dann einen Schlaf (1), dann sem_post () und ein anderes sem_getValue () gemacht. Das macht also Sinn. Warten Sie es auf 0, posten Sie es erneut (und lassen Sie den nächsten Thread fortfahren). von Semaphore -Datei "src =" https://i.sstatic.net/pviskdfg.png "/>
i denken Sie , dass der Wert dort im Wait inkrementiert wurde, wobei die Anzahl der Threads, die auf das Semaphor warteten, inkrementiert wurden. Ein Beitrag würde ihn dann verringern. Sie können es abnehmen, wenn das Testprogramm lief. Dies ist nicht der "Wert", der von sem_getValue () abgerufen wird. Wie gesagt, Sem_Value () scheint mir nur 0 oder 1 zu bekommen. < /P>
Fehlt mir etwas offensichtlich? (Das PNG -Bild ist davon): < /p>

Code: Select all

watch -d -n 0.1 'ls -tlr /dev/shm ; hexdump /dev/shm/sem.*'
< /code>
Ich führe dies aus, während das Semaphor -Testprogramm in einem anderen Fenster ausgeführt wird.  Da die Kinderfäden nach der Wartezeit schläften, verlangsamt dies die Verarbeitung so weit, dass die Mystery -Nummer (siehe Bild oben) abschließt, während jeder neue Thread aufwacht, um seine Arbeit zu erledigen.  Die Hauptänderung ist, dass die Kinderfäden ihre eigene Öffnung des Semaphors durchführen, anstatt das Elternteil zu eröffnen (und es sofort verletzt).   Dieses Spielzeugprogramm kann leicht erkennen, wann alle Fäden durchgeführt werden, und kann das Semaphor entfernen ... aber die Situation in der Produktionsumgebung ist nicht so sauber.  Daher möchte ich in der Lage sein, erkennen zu können, wann jeder Prozess mit dem Semaphor abgeschlossen ist. < /P>

#include           /* printf()                 */
#include          /* exit(), malloc(), free() */
#include 
#include       /* key_t, sem_t, pid_t      */
#include 
#include         /* shmat(), IPC_RMID        */
#include           /* errno, ECHILD            */
#include       /* sem_open(), sem_destroy(), sem_wait()..  */
#include           /* O_CREAT, O_EXEC          */

#define SEM    "pSem"

/*
https://gist.github.com/junfenglx/7412986
*/

int main (int argc, char **argv){
int i;                        /*      loop variables          */
key_t shmkey;                 /*      shared memory key       */
int shmid;                    /*      shared memory id        */
sem_t *sem;                   /*      synch semaphore         *//*shared */
pid_t pid;                    /*      fork pid                */
int *p;                       /*      shared variable         *//*shared */
unsigned int n;               /*      fork count              */
unsigned int value;           /*      semaphore value         */

/* initialize a shared variable in shared memory */
shmkey = ftok ("/dev/null", 5);       /* valid directory name and a number */
printf ("shmkey for p = %d\n", shmkey);
shmid = shmget (shmkey, sizeof (int), 0644 | IPC_CREAT);
if (shmid < 0){                           /* shared memory error check */
perror ("shmget\n");
exit (1);
}

p = (int *) shmat (shmid, NULL, 0);   /* attach p to shared memory */
*p = 0;
printf ("p=%d is allocated in shared memory.\n\n", *p);

/********************************************************/

printf ("How many children do you want to fork?\n");
printf ("Fork count: ");
scanf ("%u", &n);

printf ("What do you want the semaphore value to be?\n");
printf ("Semaphore value: ");
scanf ("%u", &value);

/* initialize semaphores for shared processes */

/* fork child processes */
for (i = 0; i < n; i++){
pid = fork ();
if (pid < 0)              /* check for error      */
printf ("Fork error.\n");
else if (pid == 0)
break;                  /* child processes */
else {
printf("thread #%d: pid=%d\n", i, pid);
}
}

/******************************************************/
/******************   PARENT PROCESS   ****************/
/******************************************************/
if (pid != 0){
int ret = 0;

/* wait for all children to exit */

while (pid = waitpid (-1, NULL, 0)){
if (errno == ECHILD)
break;
}

printf ("\nParent: All children have exited.\n");

ret = sem_unlink(SEM);
if (ret != 0) {
printf("\nParent: unlink returned %d\n", ret, errno);
}

/* shared memory detach */
shmdt (p);
shmctl (shmid, IPC_RMID, 0);

/* cleanup semaphores */
printf("sem_destroy return value:%d\n",sem_destroy (sem));
exit (0);
}

/******************************************************/
/******************   CHILD PROCESS   *****************/
/******************************************************/
else{
int tid = pid; // gettid();

// each thread opens the semaphore itself
sem = sem_open (SEM, O_CREAT, 0644, value);

if (sem == SEM_FAILED) {
printf("child #%d, %d: sem_open failed, errno=%d\n", i, tid, errno);
exit;
}

/* name of semaphore is "pSem", semaphore is reached using this name */
/* if a crash occurs during the execution         */
printf ("#%d: semaphore initialized.\n\n", i);

int value=0;
int ret = 0;

sem_wait (sem);           /* P operation */
printf ("  Child(%d) is in critical section.\n", i);
ret = sem_getvalue(sem, &value);
printf("  #%d: ret=%d, value=%d\n", i, ret, value);
sleep (1);
*p += i % 3;              /* increment *p by 0, 1 or 2 based on i */
printf ("  Child(%d) new value of *p=%d.\n", i, *p);
sem_post (sem);           /* V operation */
ret = sem_getvalue(sem, &value);
printf("  #%d: ret=%d, value=%d\n", i, ret, value);
exit (0);
}
}
/*src:http://stackoverflow.com/a/16400833*/

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post