免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3113 | 回复: 5
打印 上一主题 下一主题

POSIX无名信号量死锁问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-04 23:37 |只看该作者 |倒序浏览
5可用积分
自己练习写了一个POSIX无名信号量的demo,
创建了两个线程,一个线程对buf实行写操作,
一个线程对buf实行读操作,利用POSIX无名信号量对临界区进行保护,
但是在一个线程进行读操作时,发生信号量死锁.以下是代码:

  1. #include <errno.h>
  2. #include <pthread.h>
  3. #include <semaphore.h>
  4. #include <signal.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <unistd.h>

  8. #define BUF_SIZE 256

  9. static sem_t g_sem;
  10. static pthread_once_t g_once = PTHREAD_ONCE_INIT;

  11. static char g_buf[BUF_SIZE];

  12. void init_once()
  13. {
  14.         int err;

  15.         if( -1 == ( err = sem_init( &g_sem, 0, 1 ) ) )
  16.         {
  17.                 fprintf( stderr, "sem_init error:%s\n", strerror( err ) );

  18.                 return;
  19.         }
  20. }

  21. int read_buf( char* a_buf, const size_t a_size )
  22. {
  23.         int err;

  24.         while( ( -1 == sem_wait( &g_sem ) ) && ( EINTR == errno ) );

  25.         if( EINTR != errno )
  26.         {
  27.                 return -1;
  28.         }

  29.         strncpy( a_buf, g_buf, a_size );
  30.        
  31.         return sem_post( &g_sem );
  32. }

  33. int write_buf( const char* a_buf, const size_t a_size )
  34. {
  35.         while( ( -1 == sem_wait( &g_sem ) ) && ( EINTR == errno ) );

  36.         if( EINTR != errno )
  37.         {
  38.                 return -1;
  39.         }

  40.         strncpy( g_buf, a_buf, a_size );
  41.        
  42.         return sem_post( &g_sem );
  43. }

  44. void* run1( void* arg )
  45. {
  46.         const char k_data_buf[] = "Nothing is impossible!\n";

  47.         write_buf( k_data_buf, sizeof( k_data_buf ) );

  48.         fprintf( stderr, "Written data ok!\n"  );

  49.         return NULL;
  50. }

  51. void start_thd1()
  52. {
  53.         pthread_t thd;
  54.        
  55.         pthread_create( &thd, NULL, run1, NULL );

  56.         pthread_join( thd, NULL );
  57. }


  58. void* run2( void* arg )
  59. {
  60.         char k_data_buf[BUF_SIZE];
  61.         k_data_buf[BUF_SIZE-1] = '\0';
  62.        
  63.        
  64.         fprintf( stderr, "----------run2--------\n" );

  65.         read_buf( k_data_buf, sizeof( k_data_buf ) );

  66.         fprintf( stderr, "%s\n", k_data_buf );

  67.         return NULL;
  68. }

  69. void start_thd2()
  70. {
  71.         pthread_t thd;
  72.        

  73.         pthread_create( &thd, NULL, run2, NULL );

  74.         pthread_join( thd, NULL );
  75. }

  76. int main( int argc, char** argv )
  77. {
  78.         pthread_once( &g_once, init_once );

  79.         start_thd1();

  80.         start_thd2();
  81.        
  82.         return 0;
  83. }
复制代码


第二个线程调用read_buf时,死在:
while( ( -1 == sem_wait( &g_sem ) ) && ( EINTR == errno ) );
我感觉不是死循环,而是调用sem_wait导致死锁.
程序运行的结果是:
第一个线程的写操作能执行,第二个线程挂了

不知道是什么原因,请高手指教,谢谢!!!!!!!!!!!!!

最佳答案

查看完整内容

下面的这个条件错误。【 if( EINTR != errno ) { return -1; }】在此条件下,在没有中断的正常情况下,都返回-1了。造成信号量没有释放。

论坛徽章:
0
2 [报告]
发表于 2009-11-04 23:37 |只看该作者

回复 #1 osmanthusgfy 的帖子

下面的这个条件错误。
【        if( EINTR != errno )
        {
                return -1;
        }

在此条件下,在没有中断的正常情况下,都返回-1了。
造成信号量没有释放。

论坛徽章:
0
3 [报告]
发表于 2009-11-05 08:38 |只看该作者

回复 #1 osmanthusgfy 的帖子

没人研究过这方面的东东?

论坛徽章:
7
酉鸡
日期:2013-10-30 17:17:51水瓶座
日期:2014-01-25 14:47:21天秤座
日期:2014-02-20 09:49:50处女座
日期:2014-11-04 17:44:082015年亚洲杯之中国
日期:2015-03-09 17:21:312015亚冠之北京国安
日期:2015-06-01 16:58:552015亚冠之山东鲁能
日期:2015-06-19 11:30:08
4 [报告]
发表于 2009-11-05 09:10 |只看该作者
3楼正解啊!!

论坛徽章:
1
黑曼巴
日期:2020-02-27 22:54:26
5 [报告]
发表于 2009-11-05 14:44 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
6 [报告]
发表于 2009-11-05 22:51 |只看该作者
原帖由 c/unix 于 2009-11-5 14:44 发表


3楼指明了你程序的read_buf里为什么会组塞。

跟你说下怎么改吧
if( EINTR != errno )
{
    return -1;
}
用法根本就是错误的。

因为的sem_wait已经返回成功了也就是返回值是0。
但是你的这个i ...

c/unix大哥,感谢你更进一步指正错误,非常感谢!!!!!!!!!!!!!!!!!!1
我的修改:
  while( ( -1 == sem_wait( &g_sem ) ) && ( EINTR == errno ) );
   if( 0 != errno )
        {
                 sem_post( &g_sem );

                return -1;
        }

还像问问:errno的值为0时对应宏是什么?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP