当前位置:  技术问答>linux和unix

我使用一个递归 mutex,因为一个可能会连续锁定它两次 ,在PC机上的x86gcc可以,但ARMGCC就不行,两个版本一样。

    来源: 互联网  发布时间:2015-10-16

    本文导语:  #include        /* 标准 I/O 函数                     */ #include      /* pthread 函数和数据结构            */ #include       /* rand() and srand() 函数           */ /* 处理请求的线程数 */ ...

#include        /* 标准 I/O 函数                     */
#include      /* pthread 函数和数据结构            */
#include       /* rand() and srand() 函数           */
/* 处理请求的线程数 */
#define NUM_HANDLER_THREADS 3

/* 程序的全局 mutex,赋值初始化它 */
/* 注意我们使用一个递归 mutex,因为一个可能会连续锁定它两次 */
pthread_mutex_t request_mutex = {0,0,0,PTHREAD_MUTEX_RECURSIVE_NP,__LOCK_INITIALIZER};
//PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

/* 程序的全局条件变量,赋值初始化它 */
pthread_cond_t  got_request   = PTHREAD_COND_INITIALIZER;

int num_requests = 0; /* 待处理的请求数,初始为 0 */

/* 单个请求的格式 */
struct request {
    int number;     /* 请求的编号 */
    struct request* next;   /* 指向下一个请求的指针,NULL 表示没有下一个 */
};

struct request* requests = NULL;     /* 请求链表头 */
struct request* last_request = NULL; /* 指向最后一个请求的指针 */

/*
 * add_request(): 向请求链表增加一个请求
 * 算法: 创建一个请求结构,添加到链表中,并把待处理的请求数加 1
 */
void
add_request(int request_num,
    pthread_mutex_t* p_mutex,
    pthread_cond_t*  p_cond_var)
{
    int rc;                     /* pthread 函数的返回值 */
    struct request* a_request;      /* 指向新添加的请求     */

    /* 创建新的请求结构 */
    a_request = (struct request*)malloc(sizeof(struct request));
    if (!a_request) {
fprintf(stderr, "add_request: out of memoryn");
exit(1);
    }
    a_request->number = request_num;
    a_request->next = NULL;

    /* 锁定 mutex,以保证排它性访问链表 */
    rc = pthread_mutex_lock(p_mutex);

    /* 把新请求添加到链表尾部,按要求更新链表指针 */
    if (num_requests == 0) {
requests = a_request;
last_request = a_request;
    }
    else {
last_request->next = a_request;
last_request = a_request;
    }

    /* 把等待的请求总数加 1 */
    num_requests++;

    /* 解锁 mutex */
    rc = pthread_mutex_unlock(p_mutex);

    /* 向条件变量发信号,表示有一个新的请求有待处理 */
    rc = pthread_cond_signal(p_cond_var);
}

/*
 * get_request(): 取得链表中第一个请求,然后从链表中删除它
 */
struct request*
get_request(pthread_mutex_t* p_mutex)
{
    int rc;                     /* pthread 函数的返回值  */
    struct request* a_request;      /* 请求指针              */

    /* 锁定 mutex,以保证排它性访问链表 */
    rc = pthread_mutex_lock(p_mutex);

    if (num_requests > 0) {
a_request = requests;
requests = a_request->next;
if (requests == NULL) {
    last_request = NULL;
}
        /* 把等待的请求总数加 1 */
num_requests--;
    }
    else {
a_request = NULL;
    }

    /* 解锁 mutex */
    rc = pthread_mutex_unlock(p_mutex);

    /* 向调用者返回这个请求 */
    return a_request;
}

/*
 * handle_request(): 处理单一请求
 * 算法: 打印一条信息,表示指定请求已被指定线程处理
 */
void
handle_request(struct request* a_request, int thread_id)
{
    struct timespec delay;  /* 延迟时间 */
    if (a_request) {
printf("Thread '%d' handled request '%d'n",
       thread_id, a_request->number);
fflush(stdout);
    }
}

/*
 * handle_requests_loop(): 处理请求的无限循环
 * 算法:如果有请求要处理,取第一个处理。然后守候指定条件变量,收到信号后
 *       重新开始循环,并把待处理的请求数加 1。
 */
void*
handle_requests_loop(void* data)
{
    int rc;                     /* pthread 函数的返回值  */
    struct request* a_request;      /* 请求指针              */
    int thread_id = *((int*)data);  /* 线程序号              */

    /* 锁定 mutex,以保证排它性访问链表 */
    rc = pthread_mutex_lock(&request_mutex);

    /* 无限循环 ... */
    while (1) {
if (num_requests > 0) {
    a_request = get_request(&request_mutex);
    if (a_request) {
handle_request(a_request, thread_id);
free(a_request);
    }
}
else {
            /* 等待请求抵达:解锁——守候——锁定——返回 */
    rc = pthread_cond_wait(&got_request, &request_mutex);
}
    }
}

/* 主线程 */
int
main(int argc, char* argv[])
{
    int        i;                                /* 循环变量 */
    int        thr_num[NUM_HANDLER_THREADS];      /* 线程序号 */
    pthread_t  p_threads[NUM_HANDLER_THREADS];   /* 线程结构 */
    struct timespec delay;  /* 延迟时间 */

    /* 创建请求处理线程 */
    for (i=0; i

    
 
 

您可能感兴趣的文章:

  • php递归使用示例(php递归函数)
  • 使用C语言递归与非递归实现字符串反转函数char *reverse(char *str)的方法
  • 如何使用递归和非递归方式反转单向链表
  • PHP递归函数返回值使用实例
  • 使用python实现递归版汉诺塔示例(汉诺塔递归算法)
  • php递归函数使用return问题
  • 使用递归实现数组求和示例分享
  • 怎样使用FTP递归获取文件夹下的所有文件及子文件夹?
  • 使用递归算法求第30位数的值
  • 基于使用递归推算指定位数的斐波那契数列值的解决方法
  • php递归函数中使用return的注意事项
  • C语言使用普通循环方法和递归求斐波那契序列示例代码
  • oracle 使用递归的性能提示测试对比
  • python使用递归解决全排列数字示例
  • oracle SQL递归的使用详解
  • 使用curl递归下载软件脚本分享
  • Java递归算法的使用分析
  • php使用递归与迭代实现快速排序示例
  • 使用go和python递归删除.ds store文件的方法
  • 概率的问题:使用递归与多次试验模拟的分析
  • Photoshop教程:图层蒙版、图层锁定及解锁、图层样式的使用介绍
  • 如何锁定源代码,一次只能有一个线程使用?
  • 使用钩子如何锁定键盘的方法分享
  • java多线程并发中使用Lockers类将多线程共享资源锁定
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 两个设备使用Jtag接口通信
  • 有关vi使用的两个视频
  • ASP.NET使用Subtract方法获取两个日期之间的天数
  • linux 下两个硬盘进行复制,用DD该如何使用????
  • Linux使用中的两个问题???
  • 关于LINUX使用时的两个问题
  • 请问如何使用gzip命令将两个文件压缩成一个
  • 关于jbuilder6使用的两个小问题,绝对给分
  • 两个简单问题:在javaBean中能用out.println()输出页面吗?javaBean中可以使用servlet建立的session对象变量值吗?
  • 急求结果!!假设一个有两个元素的信号量集S,表示了一个磁带驱动器系统,其中进程1使用磁带机A,进程2同时使用磁带机A和B,进程3使用磁带机B。
  • 请教两个小问题:一个cgywin下使用vi的问题,另一个socket的问题
  • 关于makefile里面 两个源文件之间 使用全局变量的疑惑
  • 不解决也给分。如何使用vmware?我的能用vmware运行两个操作系统吗?
  • 同一目录下的两个.java文件使用package时遇到的问题(详情请进)
  • 如何实现本地的两个JAVA程序同时访问一个链表,从而共享数据资源,是否需要使用API
  • 一块硬盘安装了两个linux操作系统,它们可以共同使用一个Swap分区吗?
  • 使用RedHat7.3的两个问题,大侠帮我
  • 那位能帮你解释这两个简单语句的使用?
  • 初次使用LINUX,装完RH7.2后,它问我启动默认桌面为GNOME 还是KDE?请问这有何区别??这两个是什么意思???
  • winform使用委托和事件来完成两个窗体之间通信的实例
  • C++ I/O 成员 tellg():使用输入流读取流指针
  • 在测试memset函数的执行效率时,分为使用Cash和不使用Cash辆种方式,该如何控制是否使用缓存?
  • C++ I/O 成员 tellp():使用输出流读取流指针
  • 求ibm6000的中文使用手册 !从来没用过服务器,现在急需使用它,不知如何使用! 急!!!!!
  • Python不使用print而直接输出二进制字符串
  • 请问:在使用oracle数据库作开发时,是使用pro*c作开发好些,还是使用库函数如oci等好一些啊?或者它们有什么区别或者优缺点啊?
  • Office 2010 Module模式下使用VBA Addressof
  • c#中SAPI使用总结——SpVoice的使用方法
  • windows下tinyxml.dll下载安装使用(c++解析XML库)
  • 使用了QWidget的程序,如何使用后台程序启动它?
  • tcmalloc内存泄露优化c++开源库下载,安装及使用介绍


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3