IPC经典问题

 IPC经典问题

 

读者写者问题

读者优先
semaphore mutex=1;//控制对rc的访问
semaphore db=1;//控制对数据库的访问
int rc=1;//正在读或想要读的进程数
void reader(void)
{
    while(1){
        down(&mutex);
        rc++;
        if(rc==1)
            down(&db);
        up(&mutex);
        read_database();
        down(&mutex);
        rc--;
        if(rc==0)
            up(&db);
        up(&mutex);
        use_data_read();
    }
}
void writer(void)
{
    while(1){
        think_up_data();
        down(&db);
        write_database();
        up(&db);
    }
}

写者优先,条件为:
(1)多个读者可以同时进行读;
(2)写者必须互斥(只允许一个写者写,同时也不能读者、写者同时进行);
(3)写者优先于读者(一旦有写者来,则后续读者必须等待,唤醒时优先考虑写者)。
注意唤醒时优先考虑写者这个条件

semaphore read=1;//用于阻塞读者
semaphore rmutex=1,wmutex=1;//用于控制对rcount和wcount的访问
semaphore db=1;//控制对数据库的访问
int rcount=wcount=0;

void reader(void)
{
    p(read); //只要有写者等待,读者就会阻塞
    p(rmutex);
    rcount++;
    if(rcount==1)
        p(db);
    v(rmutex);
    v(read);//及时释放,多个读者可以同时读

    read_database();

    p(rmutex);
    rcount--;
    if(rcount==0)
        v(db);
    v(rmutex);
}

void writer(void)
{
    p(wmutex);
    wcount++;
    if(wcount==1)
        p(read);
    v(wmutex);
    p(db);

    write_database();

    v(db);
    p(wmutex);
    wcount--;
    if(wcount==0)
        v(read);
    v(wmutex);
}


如果唤醒时读写队列平等的话
semaphore write=1;//用于阻塞写者
semaphore mutex=1;//用于控制对rc的访问
semaphore db=1;//控制对数据库的访问
int rc=0;

void reader(void)
{
    p(db);
    p(mutex);
    rc++;
    if(rc==1)
        p(write); //有读者进入,互斥写操作
    v(mutex);
    v(db); // 及时释放读写互斥信号量,允许其它读、写进程申请资源

    read_database();

    p(mutex);
    rc--;
    if(rc==0)
        v(write); //所有读者退出,允许写操作
    v(mutex);
}

void writer(void)
{
    p(db);// 互斥后续其它读者、写者
    p(write);//如有读者正在读,等待所有读者读完
    
    write_database();

    v(write);//允许后续新的第一个读者进入后互斥写操作
    v(db);//允许后续新读者及其它写者
}  

哲学家就餐问题

思路:如果一个哲学家旁边两个都不在进餐时拿起叉子是安全的。
注意状态的变化应该处于临界区,如果一个哲学家不能拿起叉子时应阻塞,
同时加入一个状态表明他饥饿,旁边的哲学家就餐完毕会通知他

#define N 5
#define LEFT (i-1)%N
#define RIGHT (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2
int state[N];//记录每个人状态的数组
semaphore mutex=1;//临界区互斥
semaphore s[N]={0};//每个哲学家一个信号量,表示能否得到两只叉子

void philosopher(int i)
{
    while(1){
        think();
        take_forks(i);
        eat();
        put_forks(i);
    }
}

void take_forks(int i)
{
    donw(&mutex);
    state[i]=HUNGRY;
    test(i);//试图得到两只叉子
    up(&mutex);
    down(&s[i]);//如果得不到叉子就阻塞
}

void put_forks(int i)
{
    down(&mutex);
    stata[i]=THINKING;
    test(LEFT);//看下左邻居现在是否能进餐
    test(RIGHT);//看下右邻居现在是否能进餐
    up(&mutex);
}

void test(int i)
{
    if(state[i]==HUNGRY && state[LEFT]!=EATING && state[RIGHT]!=EATING){
        state[i]=EATING;
        up(&s[i]);
    }
}

红黑客过河

有红客和黑客两组人员需要过河。河上有船,但是每次只能乘坐4人,且每次乘客满员时才能开船,到河对岸后空船返回。但船上乘客不能同时有3个红客 、1个黑客 或者 1个红客 、 3个黑客的组合。(其他组合安全)。请编写程序,用PV操作解决红客、黑客过河的问题。

对同步与互斥的分析:
同步关系:1. 满员才能开船;2. 红黑客满足一定的组合规则,才能有四人上船
互斥关系:红黑客对请求上船的控制
显然,此题难点在对同步关系的解决。
下面给出所写程序的算法思想:
Red():每个红客到来请求上船时执行该程序:
1.请求进入临界区;
2.首先检查本人的到来是否满足上船的组合(即4个红客或2个红客与2个黑客);
3.如果满足2个红客和2和黑客的组合,则看是否有船可上,有的话该红客上船并通知另外1个红客和2个黑客上船,然后通知船满员,并退出临界区;
4.如果满足4个红客的组合,则看是否有船可上,有的话该红客上船并通知另外3个红客上船,然后通知船满员,并退出临界区;
5.不符合上船的组合,则先退出临界区,然后在信号量S_red上等待,直到当条件满足时,有人通知其上船。
6.完毕。
Black():每个黑客到来请求上船时执行该程序,其算法与Red()完全一致;
Boat():河上的船执行该程序:
1.等待满员后开船过河;
2.空船返回,通知可以上船了,转而执行1。


semapore  boats=1;    //河上船只的数量
semapore  full=0;        //船的满员状态
semapore  S_red=0;    //控制红客上船
semapore  S_black=0; //控制黑客上船
semapore  mutex=1;   //由于互斥
int reds=0;          //等待上船的红客数
int blacks=0;         //等待上船的黑客数

Red()
{
  P(mutex);//进入临界区
  reds++;  //等待上船的红客数加1

  if(reds >=2 && blacks >=2)
    {//2个红客和黑客的组合  
       P(boats);   //准备上船,无船则等待
       take_boat();//该红客上船
       reds=reds-2;//等待上船的红客数减2
       V(S_red);   //通知另一个红客上船
        
       blacks=blacks-2;//等待上船的黑客数减2
       //通知其他两黑客上船
       V(S_black);
       V(S_black);

       V(full);//通知船满员
       V(mutex);//退出临界区
    }
  else if(reds==4)
    {//4个红客的组合
       P(boats);    //准备上船,无船则等待
       take_boat(); //该红客上船
        
       //递减等待上船的红客数,通知其他3个红客上船
       while(--reds)
         V(S_red);

       V(full);//通知船满员
       V(mutex);//退出临界区
    }
  else
   {  
       V(mutex);//退出临界区,此步必在P(S_red)之前,不然会产生死锁
       //该红客等待直至条件满足时上船
       P(S_red);
       take_boat();
   }
}

Black()
{
  P(mutex);
  blacks++;

  if(blacks >=2 && reds >=2)
    {  
       P(boats);
       take_boat();
       blacks=blacks-2;
       V(S_black);
        
       reds=reds-2;
       V(S_red);
       V(S_red);

       V(full);
       V(mutex);
    }
  else if(blacks==4)
    {  
       P(boats);
       take_boat();
       while(--blacks)
         V(S_black);

       V(full);
       V(mutex);
        
    }

  else
   {
       V(mutex);
       P(S_black);
       take_boat();
   }
}


Boat()
{
  while(TRUE){
       P(full);           //等待满员
       shove_off();   //开船过河
       boat_return();//空船返回
       V(boats);       //通知可以上船了
       }
}
该算法存在一个问题是如果2红1黑时接下来来的都是红客时,会造成饥饿现象。
改进:利用5人中必有4人满足开船条件,每5个人检查一下让其中4个人过河,红黑客算法也不用分开写了。
  • 3
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
2. 简明教程 II. 安装与配置 3. 安装前需要考虑的事项 4. Unix 系统下的安装 5. Mac OS X 系统下的安装 6. Windows 系统下的安装 7. PECL 扩展库安装 8. 还有问题? 9. 运行配置 III. 语言参考 10. 基本语法 11. 类型 12. 变量 13. 常量 14. 表达式 15. 运算符 16. 流程控制 17. 函数 18. 类与对象(PHP 4) 19. 类与对象(PHP 5) 20. 异常处理 21. 引用的解释 IV. 安全 22. 简介 23. 总则 24. 以 CGI 模式安装 25. 以 Apache 模块安装 26. 文件系统安全 27. 数据库安全 28. 错误报告 29. 使用 Register Globals 30. 用户提交的数据 31. 魔术引号 32. 隐藏 PHP 33. 保持更新 V. 特点 34. 用 PHP 进行 HTTP 认证 35. cookies 36. 会话 37. 处理 XForms 38. 文件上传处理 39. 使用远程文件 40. 连接处理 41. 数据库永久连接 42. 安全模式 43. PHP 的命令行模式 VI. 函数参考 I. .NET 函数 II. Advanced PHP debugger III. Alternative PHP Cache IV. Apache 特有函数 V. Array 数组函数 VI. Aspell 函数(已废弃) VII. BC math 高精度数学函数 VIII. Bzip2 压缩函数 IX. Calendar 日历函数 X. CCVS API Functions [deprecated] XI. Character Type Functions XII. Classes/Objects 类/对象函数 XIII. Classkit Functions XIV. ClibPDF Functions XV. COM 和 .Net(Windows)函数 XVI. Crack Functions XVII. Credit Mutuel CyberMUT functions XVIII. CURL, Client URL Library Functions XIX. Cybercash Payment Functions XX. Cyrus IMAP administration Functions XXI. Database (dbm-style) Abstraction Layer Functions XXII. Date/Time 日期/间函数 XXIII. DB++ Functions XXIV. dBase Functions XXV. DBM Functions [deprecated] XXVI. dbx Functions XXVII. Direct IO Functions XXVIII. Directory 目录函数 XXIX. DOM Functions XXX. DOM XML Functions XXXI. Error Handling and Logging Functions XXXII. Exif Functions XXXIII. File Alteration Monitor Functions XXXIV. filePro Functions XXXV. Filesystem 文件系统函数 XXXVI. Firebird/InterBase Functions XXXVII. Firebird/Interbase Functions (PDO_FIREBIRD) XXXVIII. Forms Data Format Functions XXXIX. FriBiDi Functions XL. FrontBase Functions XLI. FTP 函数 XLII. Function Handling Functions XLIII. Gettext XLIV. GMP Functions XLV. GNU Readline XLVI. GNU Recode Functions XLVII. HTTP 函数 XLVIII. Hyperwave API Functions XLIX. Hyperwave Functions L. IBM DB2, Cloudscape and Apache Derby Functions LI. ICAP Functions [deprecated] LII. iconv Functions LIII. ID3 Functions LIV. IIS Administration Functions LV. Image 图像函数 LVI. IMAP, POP3 and NNTP Functions LVII. Informix Functions LVIII. Ingres II Functions LIX. IRC Gateway Functions LX. KADM5 LXI. LDAP Functions LXII. libxml Functions LXIII. Lotus Notes Functions LXIV. LZF Functions LXV. Mail Functions LXVI. mailparse Functions LXVII. Math 数学函数 LXVIII. MaxDB PHP Extension LXIX. MCAL Functions LXX. Mcrypt Encryption Functions LXXI. MCVE Payment Functions LXXII. Memcache Functions LXXIII. Mhash Functions LXXIV. Microsoft SQL Server and Sybase Functions (PDO_DBLIB) LXXV. Microsoft SQL Server Functions LXXVI. Mimetype Functions LXXVII. Ming functions for Flash LXXVIII. Miscellaneous Functions LXXIX. mnoGoSearch Functions LXXX. Mohawk Software Session Handler Functions LXXXI. mSQL Functions LXXXII. Multibyte String Functions LXXXIII. muscat Functions LXXXIV. MySQL 函数 LXXXV. MySQL Functions (PDO_MYSQL) LXXXVI. MySQL Improved Extension LXXXVII. Ncurses Terminal Screen Control Functions LXXXVIII. Network Functions LXXXIX. Net_Gopher XC. NSAPI-specific Functions XCI. Object Aggregation/Composition Functions XCII. Object property and method call overloading XCIII. ODBC and DB2 functions (PDO_ODBC) XCIV. ODBC Functions (Unified) XCV. oggvorbis XCVI. OpenAL Audio Bindings XCVII. OpenSSL Functions XCVIII. Oracle 函数 XCIX. Oracle Functions (PDO_OCI) C. Oracle 函数(已废弃) CI. Output Control 输出控制函数 CII. Ovrimos SQL Functions CIII. Paradox File Access CIV. Parsekit Functions CV. PDF functions CVI. PDO Functions CVII. PHP / Java Integration CVIII. PHP bytecode Compiler CIX. PHP Options&Information CX. POSIX Functions CXI. PostgreSQL 数据库函数 CXII. PostgreSQL Functions (PDO_PGSQL) CXIII. PostgreSQL Session Save Handler CXIV. PostScript document creation CXV. Printer Functions CXVI. Process Control Functions CXVII. Program Execution Functions CXVIII. Pspell Functions CXIX. qtdom Functions CXX. Radius CXXI. Rar Functions CXXII. Perl 兼容正则表达式函数 CXXIII. POSIX 扩展正则表达式函数 CXXIV. runkit Functions CXXV. SDO Functions CXXVI. SDO Relational Data Access Service Functions CXXVII. SDO XML Data Access Service Functions CXXVIII. Secure Shell2 Functions CXXIX. Semaphore, Shared Memory and IPC Functions CXXX. SESAM Database Functions CXXXI. Session Handling Functions CXXXII. Shared Memory Functions CXXXIII. Shockwave Flash Functions CXXXIV. SimpleXML functions CXXXV. SNMP 函数 CXXXVI. SOAP Functions CXXXVII. Socket Functions CXXXVIII. SQLite Functions CXXXIX. SQLite Functions (PDO_SQLITE) CXL. Standard PHP Library (SPL) Functions CXLI. Stream Functions CXLII. String 字符串处理函数 CXLIII. Sybase Functions CXLIV. TCP Wrappers Functions CXLV. Tidy Functions CXLVI. Tokenizer Functions CXLVII. Unicode Functions CXLVIII. URL 函数 CXLIX. Variable 变量函数 CL. Verisign Payflow Pro Functions CLI. vpopmail Functions CLII. W32api 函数 CLIII. WDDX Functions CLIV. xattr Functions CLV. xdiff Functions CLVI. XML 语法解析函数 CLVII. XML-RPC 函数 CLVIII. XMLReader functions CLIX. XSL functions CLX. XSLT Functions CLXI. YAZ Functions CLXII. YP/NIS Functions CLXIII. Zip File Functions (Read Only Access) CLXIV. Zlib Compression Functions VII. PHP 和 Zend 引擎内部资料 44. PHP 扩展库编程 API 指南 45. Zend API:深入 PHP 内核 46. 扩展 PHP 3 VIII. FAQ:常见问题 47. 一般信息 48. 邮件列表 49. 获取 PHP 50. 数据库问题 51. 安装常见问题 52. 编译问题 53. 使用 PHP 54. PHP 和 HTML 55. PHP 和 COM 56. PHP 和其它语言 57. 从 PHP/FI 2 移植到 PHP 3 58. 从 PHP 3 移植到 PHP 4 59. 从 PHP 4 移植到 PHP 5 60. 杂类问题 IX. 附录 A. PHP 及其相关工程的历史 B. 从 PHP 4 移植到 PHP 5 C. 从 PHP 3 移植到 PHP 4 D. 从 PHP/FI 2 移植到 PHP 3 E. PHP 的调试 F. 配置选项 G. php.ini 配置选项 H. 扩展库分类 I. 函数别名列表 J. 保留字列表 K. 资源类型列表 L. 支持的协议/封装协议列表 M. 可用过滤器列表 N. 所支持的套接字传输器(Socket Transports)列表 O. PHP 类型比较表 P. 解析器代号列表 Q. 关于本手册 R. 开放出版许可协议 S. 函数索引

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值