7

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

我无法调试错误...

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<semaphore.h>
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;
} 
4

4 回答 4

26

您的基础知识错了,程序将无法运行,因此请通过基础知识并重新编写程序。

您必须进行的一些更正是:

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 并通过这个示例

于 2013-03-03T06:17:25.270 回答
18

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

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

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

要决定你想要哪个信号量 API,你没有那么多好的资源。最简单的最好是 Stevens 的“Unix Network Programming”。您可能感兴趣的部分是第 2 卷。

这两个 API 有惊人的不同。两者都支持教科书式的信号量,但 System V API 有一些优点和缺点值得一提:

  • 它建立在信号量集之上,因此一旦您使用 semget() 创建了一个对象,该对象是一组信号量而不是单个信号量
  • System V API 允许您对这些集合执行原子操作。因此您可以修改或等待集合中的多个信号量
  • SysV API 允许您等待信号量达到阈值,而不仅仅是非零。也支持等待非零阈值,但我之前的句子暗示
  • 每个 unix 上的信号量资源都非常有限。您可以使用“ipcs”命令检查这些
  • System V 信号量具有撤消功能,因此您可以确保异常程序终止不会使您的信号量处于不希望的状态
于 2015-07-23T13:33:44.597 回答
4

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

供您参考的代码:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

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;
}
于 2015-09-07T13:37:21.247 回答
1

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

    #include<stdio.h>
    #include<stdlib.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include<string.h>
    #include<malloc.h>
    #include <sys/sem.h>
    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;
    }
于 2013-03-03T09:38:03.197 回答