信号量实施

我在以下程序中遇到错误。 我想演示两个进程如何使用信号量共享变量。 谁能指导我?

我无法调试错误……

#include #include #include #include #include #include int main() { int pid,mutex=1; int semid; /* semid of semaphore set */ key_t key = 1234; /* key to pass to semget() */ int nsems = 1; /* nsems to pass to semget() */ semid=semget(key,nsems,IPC_CREAT|0666); if (semid<0) { perror("Semaphore creation failed "); } if ((pid = fork()) < 0) { perror("fork"); return 1; } else if(pid==0) { sem_wait(&semid); printf("IN CHILD PROCESS :\n"); mutex++; printf("value of shared variable =%d",mutex); sem_post(&semid); return 0; } sem_wait(&semid); printf("IN PARENT PROCESS :\n"); mutex--; printf("value of shared variable =%d",mutex); sem_post(&semid); return 0; } 

您的基础知识错误,程序将无法运行,因此请完成基础知识并重写程序。

您必须做出的一些更正是:

1)您必须创建一个信号量类型的变量

 sem_t semvar; 

2)函数sem_wait()sem_post()需要信号量变量,但是你传递了信号量id,这没有任何意义。

 sem_wait(&semvar); //your critical section code sem_post(&semvar); 

3)您正在将信号量传递给sem_wait()sem_post()而不进行初始化。 在使用之前,您必须将其初始化为1(在您的情况下),否则您将遇到死锁。

 ret = semctl( semid, 1, SETVAL, sem); if (ret == 1) perror("Semaphore failed to initialize"); 

从手册页学习信号量API并完成此示例 。

您的代码的基本问题是您混合了两个API。 不幸的是,在线资源并没有很好地指出这一点,但在类UNIX系统上有两个信号量API:

  • POSIX IPC API,它是一种标准API
  • System V API,它来自旧的Unix世界,但实际上几乎可用于所有Unix系统

查看上面的代码,您使用了System V API中的semget(),并尝试发布来自POSIX API的sem_post()。 它们不可能混合使用。

要确定您想要的信号量API,您没有那么多优秀的资源。 最简单的是史蒂文斯的“Unix网络编程”。 您可能感兴趣的部分是Vol#2。

这两个API出乎意料地不同。 两者都支持教科书风格的信号量,但System V API中有一些好处和坏点值得一提:

  • 它建立在信号量集上,所以一旦用semget()创建了一个对象,它就是一组信号量而不是一个信号量
  • System V API允许您对这些集进行primefaces操作。 所以你可以修改或等待一组中的多个信号量
  • SysV API允许您等待信号量达到阈值而不是仅为非零。 也支持等待非零阈值,但我之前的句子暗示了这一点
  • 每个unix上的信号量资源非常有限。 你可以用’ipcs’命令检查这些
  • System V信号量有一个撤消function,因此您可以确保exception程序终止不会使您的信号量处于不希望的状态

改变消费者率和生产率(使用睡眠),以更好地理解代码的操作。 下面的代码是消费者 – 生产者模拟(超过容器的最大限制)。

代码供您参考:

 #include  #include  #include  sem_t semP, semC; int stock_count = 0; const int stock_max_limit=5; void *producer(void *arg) { int i, sum=0; for (i = 0; i < 10; i++) { while(stock_max_limit == stock_count){ printf("stock overflow, production on wait..\n"); sem_wait(&semC); printf("production operation continues..\n"); } sleep(1); //production decided here stock_count++; printf("P::stock-count : %d\n",stock_count); sem_post(&semP); printf("P::post signal..\n"); } } void *consumer(void *arg) { int i, sum=0; for (i = 0; i < 10; i++) { while(0 == stock_count){ printf("stock empty, consumer on wait..\n"); sem_wait(&semP); printf("consumer operation continues..\n"); } sleep(2); //consumer rate decided here stock_count--; printf("C::stock-count : %d\n", stock_count); sem_post(&semC); printf("C::post signal..\n"); } } int main(void) { pthread_t tid0,tid1; sem_init(&semP, 0, 0); sem_init(&semC, 0, 0); pthread_create(&tid0, NULL, consumer, NULL); pthread_create(&tid1, NULL, producer, NULL); pthread_join(tid0, NULL); pthread_join(tid1, NULL); sem_destroy(&semC); sem_destroy(&semP); return 0; } 

请在下面查看信号量实现的示例代码(锁定和解锁)。

  #include #include #include  #include  #include #include #include  int main() { int key,share_id,num; char *data; int semid; struct sembuf sb={0,-1,0}; key=ftok(".",'a'); if(key == -1 ) { printf("\n\n Initialization Falied of shared memory \n\n"); return 1; } share_id=shmget(key,1024,IPC_CREAT|0744); if(share_id == -1 ) { printf("\n\n Error captured while share memory allocation\n\n"); return 1; } data=(char *)shmat(share_id,(void *)0,0); strcpy(data,"Testing string\n"); if(!fork()) { //Child Porcess sb.sem_op=-1; //Lock semop(share_id,(struct sembuf *)&sb,1); strncat(data,"feeding form child\n",20); sb.sem_op=1;//Unlock semop(share_id,(struct sembuf *)&sb,1); _Exit(0); } else { //Parent Process sb.sem_op=-1; //Lock semop(share_id,(struct sembuf *)&sb,1); strncat(data,"feeding form parent\n",20); sb.sem_op=1;//Unlock semop(share_id,(struct sembuf *)&sb,1); } return 0; }