首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >信号量只在结束时工作

信号量只在结束时工作
EN

Stack Overflow用户
提问于 2014-10-30 22:45:26
回答 1查看 141关注 0票数 1

我的密码出了个奇怪的问题。支持使用Linux信号量来防止3“列车”同时进入轨道。因此,产出必须类似于: Entra秘鲁销售秘鲁Entra玻利维亚出售玻利维亚Entra哥伦比亚销售哥伦比亚. (10倍)

它确实是这样的,首先进入其中的3个,然后其中的3个退出。但是,在最后一个周期,它的工作原理是应该的。有什么想法吗?下面是源代码:

代码语言:javascript
复制
/*semaphore.h*/
struct sembuf {
   ushort  sem_num;        /* semaphore index in array */
   short   sem_op;         /* semaphore operation */
   short   sem_flg;        /* operation flags */
};


int seminit(int idsem, int value){
   int semid = semget(idsem, 1, IPC_CREAT);
   return semid;
}

void semwait(int idsem){
  int semid = semget(idsem, 0, IPC_EXCL);
  struct sembuf sops={semid, -1, 1};

  int op = semop (semid, sops, 1);
}

void semsignal(int idsem){
  int semid = semget(idsem, 0, IPC_EXCL);
  struct sembuf sops={semid, 1, 1};
  int op = semop (semid,sops, 1);
}

这是:

代码语言:javascript
复制
/*semaforos.c*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "semaphores.h"

#define CICLOS 10


char *pais[3]={"Peru","Bolivia","Colombia"};

int *g;

void proceso(int i)
{
   int k;
   int l;

   int semid=seminit(i, -1);
   printf("\nSEMID: %d\n",semid);
   for(k=0;k<CICLOS;k++)
   {
      semwait(i);
   //Entrada a la seccción crítica
      printf("Entra %s\n",pais[i]);
      fflush(stdout);
      sleep(rand()%3);
      printf("- %s Sale\n",pais[i]);
      semsignal(i%3);
   // Salida de la sección crítica
      sleep(rand()%3);   // Espera aleatoria fuera de la sección crítica
   }
   exit(0); // Termina el proceso
}

int main()
{
   int pid;
   int status;
   int args[3];
   int i;
   srand(getpid());
   for(i=0;i<3;i++)
   {
      pid=fork(); // Crea un nuevo proceso hijo que ejecuta la función proceso()
      if(pid==0)
         proceso(i);
   }

   for(i=0;i<3;i++)
      pid = wait(&status);
 }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-31 00:06:03

要使信号量正常工作,代码应该创建一个信号量,并对所有三个进程使用该信号量。您的代码似乎为每个进程创建了一个单独的信号量。另外,在创建信号量之后,代码应该将信号量的值初始化为1,这样信号量就可以接受了。

下面是我将如何编写代码

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#define SEM_RA    (SEM_R | SEM_A)
#define SEM_FLAGS (SEM_RA | (SEM_RA >> 3) | (SEM_RA >> 6))
#define CICLOS 10

static void error( const char *msg )
{
    perror( msg );
    exit( 1 );
}

void waitSem( int semid, int semnum )
{
    struct sembuf operations = { semnum, -1, 0 };

    if ( semop( semid, &operations, 1 ) < 0 )
        error( __func__ );
}

void signalSem( int semid, int semnum )
{
    struct sembuf operations = { semnum, 1, 0 };

    if ( semop( semid, &operations, 1 ) < 0 )
        error( __func__ );
}

void proceso( char *pais, int semID )
{
    int k;

    for ( k = 0; k < CICLOS; k++ )
    {
        waitSem( semID, 0 );
        // Entrada a la sección crítica
        printf( "Entra %s ", pais );
        fflush( stdout );
        sleep( arc4random_uniform( 3 ) );   // Espera aleatoria dentro de la sección crítica
        printf("- %s Sale\n", pais );
        signalSem( semID, 0 );
        // Salida de la sección crítica
        sleep( arc4random_uniform( 3 ) );   // Espera aleatoria fuera de la sección crítica
    }

    exit(0); // Termina el proceso
}

char *paises[3] = { "Peru", "Bolivia", "Colombia" };

int main( void )
{
    int i, semID, status;
    pid_t pid;

    // create the one semaphore that will be used by all three child processes
    if ( (semID = semget( 0x1001, 1, IPC_CREAT | SEM_FLAGS )) < 0 )
        error( "Unable to create semaphore" );

    // set the semaphore count to 1 so it's ready to be taken
    if ( semctl( semID, 0, SETVAL, 1 ) < 0 )
        error( "Unable to initialize semaphore" );

    for ( i = 0; i < 3; i++ )
    {
        pid = fork();       // Crea un nuevo proceso hijo que ejecuta la función proceso()
        if ( pid == 0 )
            proceso( paises[i], semID );
    }

    for ( i = 0; i < 3; i++ )
        wait( &status );
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26664673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档