【问题标题】:simple testing of semaphores信号量的简单测试
【发布时间】:2013-11-16 23:06:18
【问题描述】:

我正在尝试创建一个简单的程序来测试信号量。我正在分叉进程并在每个进程的关键部分折磨变量 c 的值,但我得到的 c 的值仍然是 1 而不是 2。即使 mmap() 未注释。谁能向我解释我做错了什么?任何帮助,将不胜感激。我是这方面的新手。非常感谢您的宝贵时间。

int main()
{
int c = 0;
  sem_t mutex;
 sem_t mutex1;
 //  sem_t *mutex = (sem_t*)mmap(NULL, sizeof(sem_t*), PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1, 0);
 sem_init(&mutex, 0, 1);
 sem_init(&mutex1, 0, 1);

  pid_t i;
  int id = fork();
 if(id == -1)   {}
  else if(id == 0)
    {
    sem_wait (&mutex);  
   c++;
   sem_post (&mutex);
   }
   else
  {
    sem_wait (&mutex);  
   c++;
   sem_post (&mutex);
   }    
     cout<<c<<endl;
   //system("pause");
   return 0;
    }

我尝试了另一种方法,将 pshared 参数设为 1,但它仍然不起作用。 我也试过 sem_op 但还是不行。

 int main()
    {


      int c = 0;


           int sid =semget(1105,2, 0666 | IPC_CREAT);


        pid_t i;
      int id = fork();

       if(id == -1)
       {

        }
            else if(id == 0)
           {

                struct sembuf sb;
                sb.sem_num = 0;
                sb.sem_op = -1;
                sb.sem_flg = 0;
                  if((semop(sid, &sb, 1)) == -1)
            cout<<"error"<<endl;

                    c++;

                sb.sem_num = 0;
                sb.sem_op = -1;
                sb.sem_flg = 0;

                      if((semop(sid, &sb, 1)) == -1)
          cout<<"error"<<endl;

         }
         else if(id == 1)
         {

                   struct sembuf sb;

                  if((semop(sid, &sb, 1)) == -1)
            cout<<"error"<<endl;

                    c++;


                     sb.sem_num = 0;
                    sb.sem_op = -1;
                    sb.sem_flg = 0;

                      if((semop(sid, &sb, 1)) == -1)
          cout<<"error"<<endl;

          }

            cout<<c<<endl;

          return 0;

            }

【问题讨论】:

  • 请花时间正确格式化您发布的代码。
  • 我刚刚编辑了它。谢谢。
  • 请通过 indent(1) 或 IDE 中的类似功能运行您的代码 - 您的手动编辑仍然格式不一致且难以理解。请包括编译所需的标题。请排除mutex1等无关代码。

标签: unix testing shared-memory semaphore multiprocess


【解决方案1】:

如果您使用fork(),您必须在分叉的进程之间共享信号量。详情请见sem_init() manual

您也可以使用命名信号量,详情请参阅sem_open(),以及 还有a good article on the subject

【讨论】:

  • 是的,我这样做了,但它仍然不起作用。我正在运行 Linux mint 14。你认为这可能是个问题吗?谢谢。
【解决方案2】:

您的主要失误是变量c 本身不是共享的——每个进程都在自己的变量副本上运行。你想要这样的东西:

int *c;

c = mmap(NULL, sizeof(*c), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
*c = 0;

// ... later ...
++*c;

此外,关于您的 sem_init() 示例,您应该:

  • 分配正确大小的共享内存:sizeof(sem_t)not sizeof(sem_t*)
  • sem_init() 期间设置pshared 标志

fork() 之后,您可能不需要条件逻辑来区分父母与孩子。毕竟,您希望他们做同样的事情。

(另外,请不要将 POSIX 信号量命名为“互斥量”。该名称会误导匆忙的、具有 POSIX 思维的人,他们会认为您指的是不同类型的同步原语。)

关于您的 semget() 示例,您似乎在子进程中等待信号量两次 (sb.sem_op = -1)。对父项的 post-fork() 检查不正确 - 您检查返回的 PID 是否为 1(在典型的 UNIX 系统上永远不会出现),而不是返回的 PID 是否 > 0。(同样,您可能不需要让父母和孩子在这里做不同的事情。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多