APUE中文第三版11章读写锁的一个可运行的例子
来源:互联网 发布:linux网络故障排查 编辑:程序博客网 时间:2024/06/06 00:46
我的测试环境是CentOS7(内核版本3.10.0),X86_64.
头文件: wrlock.h
#ifndef _WRLOCK_H#define _WRLOCK_H#include <stdlib.h>#include <pthread.h>#include <stdio.h>struct job { struct job *j_next; struct job *j_prev; pthread_t tid; void *( *job_func)( void *);};struct queue { struct job *q_head; struct job *q_tail; pthread_rwlock_t q_lock; };int queue_init( struct queue *qp );void job_insert( struct queue *qp, struct job *jp );void job_append( struct queue *qp, struct job *jp );void job_remove( struct queue *qp, struct job *jp );struct job *job_find( struct queue *qp, pthread_t tid );#endif
队列的相关操作,这一部分与书上的基本一样。
11_14.c
#include "wrlock.h"intqueue_init( struct queue *qp ){ int err; qp->q_head = qp->q_tail = NULL; if ((err = pthread_rwlock_init(&qp->q_lock,NULL)) != 0) return err; return 0;}/* insert a job at the head of queue */void job_insert( struct queue *qp, struct job *jp ){ pthread_rwlock_wrlock(&qp->q_lock); jp->j_next = qp->q_head; jp->j_prev = NULL; if ( qp->q_head != NULL ) qp->q_head->j_prev = jp; else qp->q_tail = jp; qp->q_head = jp; pthread_rwlock_unlock(&qp->q_lock);}/* append a job on the tail of queue */void job_append( struct queue *qp, struct job *jp ){ pthread_rwlock_wrlock(&qp->q_lock); jp->j_next = NULL; jp->j_prev = qp->q_tail; if ( qp->q_tail != NULL ) qp->q_tail->j_next = jp; else qp->q_head = jp; qp->q_tail = jp; pthread_rwlock_unlock(&qp->q_lock);}voidjob_remove( struct queue *qp, struct job *jp ){ pthread_rwlock_wrlock(&qp->q_lock); /* ** remove the head job,maybe jp pointing the only job. */ if (jp == qp->q_head){ qp->q_head = jp->j_next; if (jp->j_next != NULL) jp->j_next->j_prev = NULL; else qp->q_tail = NULL; } /* ** remove the tail job, if jp pointing the only job, ** then if{} statements has executed, we can't get here. */ else if ( jp == qp->q_tail ){ qp->q_tail = jp->j_prev; jp->j_prev->j_next = NULL; } else{ jp->j_next->j_prev = jp->j_prev; jp->j_prev->j_next = jp->j_next; } pthread_rwlock_unlock(&qp->q_lock);}struct job *job_find( struct queue *qp, pthread_t tid ){ struct job *jtmp; if(pthread_rwlock_rdlock(&qp->q_lock) != 0) return NULL; for ( jtmp = qp->q_head; jtmp != NULL; jtmp = jtmp->j_next ){ if (pthread_equal(jtmp->tid,tid) != 0) break; } pthread_rwlock_unlock(&qp->q_lock); return jtmp;}
main函数部分,主线程负责初始化队列,将产生的job插入队列,job结构中有指派的线程的id,以及给出的任务(函数指针)。其他的工作线程从队列中找到属于自己的job,然后利用这个函数指针调用函数,完成任务。任务很简单,就是打印一句话。
main.c:
#include "wrlock.h"#define _GNU_SOURCEvoid *task1( void *str1 ){ printf("I am thread 1, %s\n",(char *)str1);}void *task2( void *str2 ){ printf("I am thread 2, %s\n",(char *)str2);}void *task3( void *str3 ){ printf("I am thread 3, %s\n",(char *)str3);}void *thr1_func( void *arg ) //arg points to queue.{ pthread_t tid; struct job *jp1; tid = pthread_self(); while (1){ if ((jp1 = job_find(arg,tid)) != NULL){ jp1->job_func("task completly!"); job_remove(arg,jp1); free(jp1); }else{ pthread_yield(); } }}void *thr2_func( void *arg ) //arg points to queue.{ pthread_t tid; struct job *jp2; tid = pthread_self(); while (1){ if ((jp2 = job_find(arg,tid)) != NULL){ jp2->job_func("task completly!"); job_remove(arg,jp2); free(jp2); }else{ pthread_yield(); } }}void *thr3_func( void *arg ) //arg points to queue.{ pthread_t tid; struct job *jp3; tid = pthread_self(); while (1){ if ((jp3 = job_find(arg,tid)) != NULL){ jp3->job_func("task completly!"); job_remove(arg,jp3); free(jp3); }else{ pthread_yield(); } }}int main( void ){ unsigned long n; int err; int foo; struct job *jobptr; struct queue *qptr; pthread_t tid[3]; void *(*func[3])(void *) = { task1, task2, task3 }; /* initialise the queue */ if ((qptr = malloc(sizeof( struct queue ))) == NULL) exit(-1); queue_init(qptr); /* produce task in main thread */ err = pthread_create(&tid[0],NULL,thr1_func,qptr); if (err != 0) exit(-1); else printf("create thread 1 success\n"); err = pthread_create(&tid[1],NULL,thr2_func,qptr); if (err != 0) exit(-1); else printf("create thread 2 success\n"); err = pthread_create(&tid[2],NULL,thr3_func,qptr); if (err != 0) exit(-1); else printf("create thread 3 success\n"); for ( n = 1; n <= 10; n++){ if ((jobptr = malloc(sizeof(struct job))) == NULL) exit(-1); foo = rand()%3; jobptr->tid = tid[foo]; jobptr->job_func = func[foo]; job_insert(qptr,jobptr); } sleep(10); exit(0);}
0 0
- APUE中文第三版11章读写锁的一个可运行的例子
- --总结加一个完整的可运行的Thrift例子
- APUE 第三章 文件I/O 文件的打开、读写、设置等
- 文件读写的一个例子
- apue第三版学习环境的配置
- APUE 第七章 进程的运行环境
- apue第三版 在信号处理程序中调用不可再入函数 的例子遇到的问题
- Thrift源码分析(八)--总结加一个完整的可运行的Thrift例子
- Javascript 读写文件的一个例子
- 一个VC读写刷卡器的例子
- 一个GDAL的读写数据例子
- 一个GDAL的读写数据例子
- bcb 读写ini 配置文件的一个例子
- 一个文件读写的简易例子
- c语言文件读写的一个例子
- 一个读写ini文件属性的例子
- 【MTK】一个寄存器读写的例子
- 一个可拖动div的例子
- 两张图总结 Neutron 架构 - 每天5分钟玩转 OpenStack(74)
- poj-3617Best Cow Line(将字符串逆序排列 与原字符串作比较)
- Linux下安装及操作SQL数据库
- 使用mockserver来进行http接口mock
- 缓冲区与Buffer
- APUE中文第三版11章读写锁的一个可运行的例子
- PHP入门1.5
- Python基础教程——第三章 使用字符串
- 重学Spring——IOC
- 50. Pow(x, n)
- 【u107】数字游戏(bds)
- [leetcode] 80. Remove Duplicates from Sorted Array II
- 二叉树的三种遍历图解
- sklearn 源码解析 基本线性模型 base.py