little_tony 发表于 2014-07-20 22:24

关于信号量访问临界区的exit(1)是否会退出临界区的疑问?

有一个实验,是关于进程间通信-信号量详解及编程实例 (具体请见下文网址)
http://blog.csdn.net/xiajun07061225/article/details/8475738
其中对于控制临界区的一段代码,我提出了几点由于作为新手不懂的疑问。


1,代码56 行 exit(EXIT_FAILURE); 是退出进程。本进程带参数的进程(以下简称X进程)执行了P操作,而现在不带参数的进程(以下简称O进程)执行到此,则会直接退出进程。那现在不就只剩下X进程了吗?O进程则不存在了,则不存在临界区的问题了吧?可是实验的结果,是好像O进程执行到 exit(EXIT_FAILURE);并没有退出进程,好像挂起似的,等待X进程V操作了,才又往下执行。( exit(EXIT_FAILURE)没有让它退出进程?)知识浅浅,急求解疑。谢谢。

2,本实验是一个程序执行两个实例,请问:一个程序执行两个实例(进程),其是否代码段一样,而数据段却有一份拷贝,两个进程共享代码却分开数据?比如此处的op_char,在各自的进程中,值分别是X或O,而且在另一个进程改变其值时,本进程好像没有改变。

谢谢。#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#include <sys/sem.h>//包含信号量定义的头文件

//联合类型semun定义
union semun{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};

//函数声明
//函数:设置信号量的值
static int set_semvalue(void);
//函数:删除信号量
static void del_semvalue(void);
//函数:信号量P操作
static int semaphore_p(void);
//函数:信号量V操作
static int semaphore_v(void);

static int sem_id;//信号量ID


int main(int argc,char *argv[])
{
    int i;
    int pause_time;
    char op_char = 'O';

    srand((unsigned int)getpid());

    //创建一个新的信号量或者是取得一个已有信号量的键
    sem_id = semget((key_t)1234,1,0666 | IPC_CREAT);

    //如果参数数量大于1,则这个程序负责创建信号和删除信号量
    if(argc > 1)
    {
      if(!set_semvalue())
      {
            fprintf(stderr,"failed to initialize semaphore\n");
      exit(EXIT_FAILURE);
      }

      op_char = 'X';//对进程进行标记
      sleep(5);
    }

    //循环:访问临界区
    for(i = 0;i < 10;++i)
    {
      //P操作,尝试进入缓冲区
      if(!semaphore_p())
      exit(EXIT_FAILURE);
      printf("%c",op_char);
      fflush(stdout);//刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上

      pause_time = rand() % 3;
      sleep(pause_time);

      printf("%c",op_char);
      fflush(stdout);

      //V操作,尝试离开缓冲区
      if(!semaphore_v())
      exit(EXIT_FAILURE);
      pause_time = rand() % 2;
      sleep(pause_time);
    }

    printf("\n %d - finished \n",getpid());

    if(argc > 1)
    {
      sleep(10);
      del_semvalue();//删除信号量
    }
}


//函数:设置信号量的值
static int set_semvalue(void)
{
    union semun sem_union;
    sem_union.val = 1;

    if(semctl(sem_id,0,SETVAL,sem_union))
      return 0;

    return 1;
}

//函数:删除信号量
static void del_semvalue(void)
{
    union semun sem_union;

    if(semctl(sem_id,0,IPC_RMID,sem_union))
      fprintf(stderr,"Failed to delete semaphore\n");
}

//函数:信号量P操作:对信号量进行减一操作
static int semaphore_p(void)
{
    struct sembuf sem_b;

    sem_b.sem_num = 0;//信号量编号
    sem_b.sem_op = -1;//P操作   
    sem_b.sem_flg = SEM_UNDO;

    if(semop(sem_id,&sem_b,1) == -1)
    {
      fprintf(stderr,"semaphore_p failed\n");
      return 0;
    }

    return 1;
}

//函数:信号量V操作:对信号量进行加一操作
static int semaphore_v(void)
{
    struct sembuf sem_b;

    sem_b.sem_num = 0;//信号量编号
    sem_b.sem_op = 1;//V操作   
    sem_b.sem_flg = SEM_UNDO;

    if(semop(sem_id,&sem_b,1) == -1)
    {
      fprintf(stderr,"semaphore_v failed\n");
      return 0;
    }

    return 1;

}
页: [1]
查看完整版本: 关于信号量访问临界区的exit(1)是否会退出临界区的疑问?