簡體   English   中英

將信號量添加到程序-Linux中的C

[英]Adding Semaphore to a program - C in Linux

我對編程比較陌生,尤其是在C語言中。 我得到了一個任務,用C編寫一個簡單程序並在Linux中執行它。 我已經編寫了如下代碼:

#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
#define BUFSZ 4096

int shmid;
int shmkey = 12222;

int main()
 {
  /* ----- Creating Shared memory ----- */
  shmid=shmget(IPC_PRIVATE,BUFSZ,0666);  
  if(shmid<0)
      {
        perror("shmget");
        exit(EXIT_FAILURE);
      }
  printf(" Segment Created: %d \n", shmid);


  /* ----- Attaching Memory to Shared memory ----- */
  char *shmbuf;    
  if((shmbuf=shmat(shmid,0,0))<0)
      {
        perror("shmat");
        exit(EXIT_FAILURE);
      }

  printf("Segmet Attached at %p \n", shmbuf);
  //system("ipcs -m");


  /* ----- Creating Process Using Fork ----- */
  int p,i;               //i is counter
  for (i=1; i<=20; i++)  //loop for counter
    {
     p=fork();          //defining fork
     if (p<0)
       {
         printf("Fork Failed");   //Fork Fails if P<0
         exit(-1);
       }
     else if (p==0)      //Child Process
       {
         printf("Counter: %d\t Process ID: %d\n" ,i,getpid()); 
         //Prints Counter Value and Process ID. 
       }
     else      //Parent Process
       {
         wait(NULL);  //Waits Child Process to Complete
         exit(0);
       } 
    }

 /* ----- Deattaching Memory -----*/

 if((shmdt(shmbuf))<0)    
       {
          perror("shmat");
          exit(EXIT_FAILURE);
       }

  printf("Segmet Deattached at %p \n", shmbuf);
  //system("ipcs -m");

  /* ----- Exiting Program ----- */
  exit(0);
  puts("\n End\n");

 }

現在,我必須使用semget(),semop()和semctl()將信號量的概念應用於該程序。 我可以在程序中如何使用這三個功能獲得幫助嗎?

信號量優於其他同步機制的優點是,它們可用於同步嘗試訪問同一資源的兩個相關或不相關的進程。 相關流程

如果新流程是從現有流程中創建的,則認為這些流程是相關的,最終會導致創建流程的資源重復。 這樣的過程稱為相關過程。 以下示例顯示如何同步相關過程。

文件prog.c

#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>

int main(int argc, char **argv) {   int fd, i,count=0,nloop=10,zero=0,*ptr;   sem_t mutex;

  //open a file and map it into memory

  fd = open("log.txt",O_RDWR|O_CREAT,S_IRWXU);   write(fd,&zero,sizeof(int));   ptr = mmap(NULL,sizeof(int),PROT_READ |PROT_WRITE,MAP_SHARED,fd,0);   close(fd);

  /* create, initialize semaphore */   if( sem_init(&mutex,1,1) < 0)
    {
      perror("semaphore initilization");
      exit(0);
    }   if (fork() == 0) { /* child process*/
    for (i = 0; i < nloop; i++) {
      sem_wait(&mutex);
      printf("child: %d\n", (*ptr)++);
      sem_post(&mutex);
    }
    exit(0);   }   /* back to parent process */   for (i = 0; i < nloop; i++) {
    sem_wait(&mutex);
    printf("parent: %d\n", (*ptr)++);
    sem_post(&mutex);   }   exit(0); }

gcc prog.c -lpthread

在此示例中,相關的進程訪問一個公用的內存,該內存已同步。 不相關的過程

如果兩個進程彼此未知並且它們之間不存在任何關系,則稱這些進程無關。 例如,兩個不同程序的實例是不相關的過程。 如果此類程序嘗試訪問共享資源,則可以使用信號量來同步其訪問。 以下源代碼演示了這一點:

文件1:server.c

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define SHMSZ 27
char SEM_NAME[]= "vik";

int main()
{
  char ch;
  int shmid;
  key_t key;
  char *shm,*s;
  sem_t *mutex;

  //name the shared memory segment
  key = 1000;

  //create & initialize semaphore
  mutex = sem_open(SEM_NAME,O_CREAT,0644,1);
  if(mutex == SEM_FAILED)
    {
      perror("unable to create semaphore");
      sem_unlink(SEM_NAME);
      exit(-1);
    }

  //create the shared memory segment with this key
  shmid = shmget(key,SHMSZ,IPC_CREAT|0666);
  if(shmid<0)
    {
      perror("failure in shmget");
      exit(-1);
    }

  //attach this segment to virtual memory
  shm = shmat(shmid,NULL,0);

  //start writing into memory
  s = shm;
  for(ch='A';ch<='Z';ch++)
    {
      sem_wait(mutex);
      *s++ = ch;
      sem_post(mutex);
    }

  //the below loop could be replaced by binary semaphore
  while(*shm != '*')
    {
      sleep(1);
    }
  sem_close(mutex);
  sem_unlink(SEM_NAME);
  shmctl(shmid, IPC_RMID, 0);
  _exit(0);
}

gcc server.c -lpthread -o服務器

文件2:client.c

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define SHMSZ 27
char SEM_NAME[]= "vik";

int main()
{
  char ch;
  int shmid;
  key_t key;
  char *shm,*s;
  sem_t *mutex;

  //name the shared memory segment
  key = 1000;

  //create & initialize existing semaphore
  mutex = sem_open(SEM_NAME,0,0644,0);
  if(mutex == SEM_FAILED)
    {
      perror("reader:unable to execute semaphore");
      sem_close(mutex);
      exit(-1);
    }

  //create the shared memory segment with this key
  shmid = shmget(key,SHMSZ,0666);
  if(shmid<0)
    {
      perror("reader:failure in shmget");
      exit(-1);
    }

  //attach this segment to virtual memory
  shm = shmat(shmid,NULL,0);

  //start reading
  s = shm;
  for(s=shm;*s!=NULL;s++)
    {
      sem_wait(mutex);
      putchar(*s);
      sem_post(mutex);
    }

  //once done signal exiting of reader:This can be replaced by another semaphore
  *shm = '*';
  sem_close(mutex);
  shmctl(shmid, IPC_RMID, 0);
  exit(0);
}

gcc client.c -lpthread -o客戶端

以上可執行文件(客戶端和服務器)演示了如何在完全不同的進程之間使用信號量。

除了上面顯示的應用程序之外,信號燈還可以協同使用來訪問資源。 請注意,信號量不是互斥體。 Mutex允許串行訪問資源,而信號量除了允許串行訪問外,還可以用於並行訪問資源。 例如,考慮n個用戶正在訪問資源R。 當使用互斥鎖時,我們將需要互斥鎖“ m”來鎖定和解鎖資源,從而一次僅允許一個用戶使用資源R。相反,信號量可以允許n個用戶同步訪問資源R。 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM