linux实验-linux进程同步

首先这次测验采用的是封装的头文件:

在root角色中使用命令cd /usr/include touch ph_head.h vim ph_head.h

封装的头文件有:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/wait.h>

#include <errno.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <signal.h>

#include <string.h>

#include <stdbool.h>

#include <dirent.h>

#include <time.h>

#include <math.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <sys/shm.h>

#include <sys/sem.h>

#include <semaphore.h>

#include <pthread.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <netinet/in.h>

#include <linux/input.h>

#include <sys/mman.h>

【5-13-change】利用fork产生4个进程,模拟他们互斥写文件的过程:不是真写文件,是用输出语句输出“我要写文件”,“我正在写文件”,“我写完文件了”,输出体现出他们的互斥并发。两句“我正在写文件”不可能紧挨着输出。

代码:

#include<ph_head.h>

int file_ =  0;

char ch;

int main(int argc,char argv[])

{

  pid_t pid;

  pid_t pids[4];

  int i = 0;

  int j = 0;

  int ph = 0;

  struct sembuf sem_b;

  sem_b.sem_num = 0;

  sem_b.sem_flg = SEM_UNDO;

  file_ = semget(IPC_PRIVATE,1,0666|IPC_CREAT);

  semctl(file_,0,SETVAL,1);

  for(i=0;i<=3;i++)

  {

    pid = fork();

    if(pid==0)

    {

      while(1){

        ph = rand()%4;

        printf("ph program:进程%d 说---我要写文件\n",i+1);

        sem_b.sem_op = -1;

        semop(file_,&sem_b,1);//P-wait

        printf("ph program:进程%d 说---我正在写文件\n",i+1);

        sleep(3);

        sem_b.sem_op = 1;

        semop(file_,&sem_b,1);

        printf("ph program:进程%d 说---我写完文件了\n",i+1);

}

}else{pids[i] = pid;}

}//for

do{

  ch = getchar();

  if(ch=='q')

    for(i=0;i<=3;i++)

      kill(pids[i],SIGTERM);

}while(ch!='q');}

运行截图1:

运行截图2:

总结分析:

  1. 因为fork产生四个进程,所以pid_t的数组中有4个元素;pid_t pids[4];
  2. 直接运用struct sembuf方法实现P、V操作;
  3. 定义整型变量file_,为设置为信号量,赋初值为1,表示可以写一个文件;
  4. 定义整型变量ph并运用rand()函数来随机生成值,达到四个进程公平竞争,因此在输出结果中发现顺序也不一样,因为rand()函数。
  5. 借用for循环中的变量i表明是哪个进程在写文件,同时显示的为进程1-4,而非0-3.
  6. 当输入’q’时表示运行完成。

【5-14】变化:信号量模拟实现进程并发,一个盘子只能放1个水果,母亲放苹果,父亲放桔子,儿子吃苹果,女儿吃桔子,利用printf输出字符串模拟母亲和孩子的动作,如输出“放苹果”,“吃桔子”等。孩子吃水果速度用sleep随机时间控制,要求输出应能体现正确同步逻辑顺序。

代码:

#include<ph_head.h>

int e_ph;//empty of plate

int f_ph;//fruit

int apple_ph;

int orange_ph;

int waitsem(int sem_id)

{

  struct sembuf sem_b;

  sem_b.sem_num = 0;

  sem_b.sem_op = -1;

  sem_b.sem_flg =  SEM_UNDO;

  if(semop(sem_id,&sem_b,1)==-1)

  {

    fprintf(stderr,"ph program:P failed \n");

    return 0;}

  return 1;

}

int signalsem(int sem_id)

{

  struct sembuf sem_b;

  sem_b.sem_num = 0;

  sem_b.sem_op = 1;

  sem_b.sem_flg =  SEM_UNDO;

  if(semop(sem_id,&sem_b,1)==-1)

  {

    fprintf(stderr,"V failed \n");

    return 0;}

  return 1;

}

int main(int argc,char argv[])

{

  pid_t pid;

  pid_t pids[4];

  int i = 0;

  char ch;

  e_ph = semget(IPC_PRIVATE,1,0666|IPC_CREAT);

  f_ph = semget(IPC_PRIVATE,1,0666|IPC_CREAT);

  apple_ph = semget(IPC_PRIVATE,1,0666|IPC_CREAT);

  orange_ph = semget(IPC_PRIVATE,1,0666|IPC_CREAT);

  semctl(e_ph,0,SETVAL,1);//大于0表示盘子可以放,1为盘子可放数量

  semctl(f_ph,0,SETVAL,0);//f为是否有水果,0为没有

  semctl(apple_ph,0,SETVAL,0);//apple为是否有苹果,0为没有

  semctl(orange_ph,0,SETVAL,0);//orange为是否有桔子,0为没有

  for(i=0;i<=3;i++)

  {

    pid = fork();

if(pid>0) pids[i] = pid;

    if(pid==0&&i==0)//father

      while(1)

        {

          waitsem(e_ph);

          sleep(5);

          signalsem(f_ph);

          signalsem(orange_ph);

          printf("ph program:父亲已经放好桔子\n");}

if(pid==0&&i==1)//mother

      while(1)

        {

          waitsem(e_ph);

          sleep(5);

          signalsem(f_ph);

          signalsem(apple_ph);

          printf("ph program:母亲已经放好苹果\n");}

if(pid==0&&i==2)//daughter

      while(1)

        {

          printf("ph program:女儿想吃桔子\n");

          waitsem(f_ph);

          waitsem(orange_ph);

          printf("ph program:女儿正在吃桔子\n");

          sleep(rand()%6);

          signalsem(orange_ph);

          signalsem(e_ph);

          printf("ph program:女儿吃完了桔子\n");

        }

    if(pid==0&&i==3)

      while(1)

        {

          printf("ph program:儿子想吃苹果\n");

          waitsem(f_ph);

          waitsem(apple_ph);

          printf("ph program:儿子正在吃苹果\n");

          sleep(rand()%6);

          signalsem(apple_ph);

          signalsem(e_ph);

          printf("ph program:儿子吃完了苹果\n");

        }

}//for

do{

  ch = getchar();

  if(ch=='q')

    for(i=0;i<=3;i++)

      kill(pids[i],SIGTERM);

  }while(ch!='q');

}//main

运行截图1:

运行截图2:

分析总结:

  1. 因为fork产生四个进程,所以pid_t的数组中有4个元素;pid_t pids[4];
  2. 将struct sembuf方法封装在waitsem和signalsem,通过调用waitsem和signalsem实现P、V操作

3.定义整型变量e_ph,f_ph,apple_ph和orange_ph,为设置为信号量:

e_ph表示大于0表示盘子可以放,1为盘子可放数量,赋初值为1;

f_ph表示是否有水果,0为没有,赋初值为0;

apple_ph表示是否有苹果,0为没有,赋初值为0;

orange_ph表示是否有桔子,0为没有,赋初值为0;

4.运用rand()函数来随机生成值,实现孩子吃水果速度用sleep随机时间控制,这因此也是输出结果中唯一的不同(时间不同),因为rand()函数。

5.运用for循环顺序的进行四个行为的进行。

对此我也尝试了使用rand()函数达到随机的效果,但是发现有个问题,就是信号量可以限制住苹果和桔子是否放和单一水果的效果,但是对于儿子和女儿来说,他们可以多次表示想吃苹果/桔子,有时候会连着输出两句“儿子想吃苹果”或者“女儿想吃桔子”,因此rand()不好用。

6.当输入’q’时表示运行完成。

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值