APUE 线程 - 程序清单
APUE 线程 - 程序清单
程序清单11-1 打印线程ID
- #include "util.h"
- #include<pthread.h>
- pthread_t ntid;
- void
- printids(const char *s)
- {
- pid_t pid;
- pthread_t tid;
- pid = getpid();
- tid = pthread_self();
- //之所以打印16进制,便于pthread_t是结构体的话看地址;
- printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int)pid,
- (unsigned int)tid, (unsigned int)tid);
- }
- void *
- thr_fn(void *arg)
- {
- printids("new thread: ");
- return((void *)0);
- }
- int
- main(void)
- {
- int err;
- err = pthread_create(&ntid, NULL, thr_fn, NULL);
- if (err != 0)
- err_quit("can't create thread: %s\n", strerror(err));
- printids("main thread:");
- sleep(1);//确保会运行新线程
- exit(0);
- }
程序清单11-2 获得线程退出状态
- #include "util.h"
- #include <pthread.h>
- void *
- thr_fn1(void *arg)
- {
- printf("thread 1 returning\n");
- return((void *)1);
- }
- void *
- thr_fn2(void *arg)
- {
- printf("thread 2 exiting\n");
- pthread_exit((void *)2);
- }
- int
- main(void)
- {
- int err;
- pthread_t tid1, tid2;
- void *tret;
- err = pthread_create(&tid1, NULL, thr_fn1, NULL);
- if (err != 0)
- err_quit("can't create thread 1: %s\n", strerror(err));
- err = pthread_create(&tid2, NULL, thr_fn2, NULL);
- if (err != 0)
- err_quit("can't create thread 2: %s\n", strerror(err));
- err = pthread_join(tid1, &tret);
- if (err != 0)
- err_quit("can't join with thread 1: %s\n", strerror(err));
- printf("thread 1 exit code %d\n", (int)tret);
- err = pthread_join(tid2, &tret);
- if (err != 0)
- err_quit("can't join with thread 2: %s\n", strerror(err));
- printf("thread 2 exit code %d\n", (int)tret);
- exit(0);
- }
程序清单11-3 pthread_exit 的參数不对使用
- #include "util.h"
- #include <pthread.h>
- struct foo {
- int a, b, c, d;
- };
- void
- printfoo(const char *s, const struct foo *fp)
- {
- printf(s);
- printf(" structure at 0x%x\n", (unsigned)fp);
- printf(" foo.a = %d\n", fp->a);
- printf(" foo.b = %d\n", fp->b);
- printf(" foo.c = %d\n", fp->c);
- printf(" foo.d = %d\n", fp->d);
- }
- void *
- thr_fn1(void *arg)
- {
- struct foo foo = {1, 2, 3, 4};
- printfoo("thread 1:\n", &foo);
- pthread_exit((void *)&foo);
- //这里是自己主动变量。退出的时候仅仅是告知监听者退出状态码所在的地址。可是里面的内容在函数退出时就变了;
- }
- void *
- thr_fn2(void *arg)
- {
- printf("thread 2: ID is %ld\n", pthread_self());//这里最好用长整型;
- pthread_exit((void *)0);
- }
- int
- main(void)
- {
- int err;
- pthread_t tid1, tid2;
- struct foo *fp;
- err = pthread_create(&tid1, NULL, thr_fn1, NULL);
- if (err != 0)
- err_quit("can't create thread 1: %s\n", strerror(err));
- err = pthread_join(tid1, (void *)&fp);
- if (err != 0)
- err_quit("can't join with thread 1: %s\n", strerror(err));
- sleep(1);
- printf("parent starting second thread\n");
- err = pthread_create(&tid2, NULL, thr_fn2, NULL);
- if (err != 0)
- err_quit("can't create thread 2: %s\n", strerror(err));
- sleep(1);
- printfoo("parent:\n", fp);
- exit(0);
- }
程序清单11-4 线程清理处理程序
- #include "util.h"
- #include <pthread.h>
- void
- cleanup(void *arg)
- {
- printf("cleanup: %s\n", (char *)arg);
- }
- void *
- thr_fn1(void *arg)
- {
- printf("thread 1 start\n");
- pthread_cleanup_push(cleanup, "thread 1 first handler");
- pthread_cleanup_push(cleanup, "thread 1 second handler");
- printf("thread 1 push complete\n");
- if (arg)
- return((void *)1);
- //假设从启动例程中返回而终止不会调用清理函数。
- pthread_cleanup_pop(0);
- pthread_cleanup_pop(0);
- return((void *)1);
- }
- void *
- thr_fn2(void *arg)
- {
- printf("thread 2 start\n");
- pthread_cleanup_push(cleanup, "thread 2 first handler");
- pthread_cleanup_push(cleanup, "thread 2 second handler");
- printf("thread 2 push complete\n");
- if (arg)
- pthread_exit((void *)2);
- pthread_cleanup_pop(0);
- pthread_cleanup_pop(0);
- pthread_exit((void *)2);
- }
- int
- main(void)
- {
- int err;
- pthread_t tid1, tid2;
- void *tret;
- err = pthread_create(&tid1, NULL, thr_fn1, (void *)1);
- if (err != 0)
- err_quit("can't create thread 1: %s\n", strerror(err));
- err = pthread_create(&tid2, NULL, thr_fn2, (void *)1);
- if (err != 0)
- err_quit("can't create thread 2: %s\n", strerror(err));
- err = pthread_join(tid1, &tret);
- if (err != 0)
- err_quit("can't join with thread 1: %s\n", strerror(err));
- printf("thread 1 exit code %d\n", (int)tret);
- err = pthread_join(tid2, &tret);
- if (err != 0)
- err_quit("can't join with thread 2: %s\n", strerror(err));
- printf("thread 2 exit code %d\n", (int)tret);
- exit(0);
- }
程序清单11-5 使用相互排斥量保护数据结构
- #include <stdlib.h>
- #include <stdio.h>
- #include <pthread.h>
- struct foo {
- int f_count;
- pthread_mutex_t f_lock;
- /* ... more stuff here ... */
- };
- struct foo *
- foo_alloc(void) /* allocate the object */
- {
- struct foo *fp;
- if ((fp = malloc(sizeof(struct foo))) != NULL) {
- fp->f_count = 1;
- if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
- free(fp);
- return(NULL);
- }
- /* ... continue initialization ... */
- }
- return(fp);
- }
- void
- foo_hold(struct foo *fp) /* add a reference to the object */
- {
- pthread_mutex_lock(&fp->f_lock);
- fp->f_count++;
- pthread_mutex_unlock(&fp->f_lock);
- }
- void
- foo_rele(struct foo *fp) /* release a reference to the object */
- {
- pthread_mutex_lock(&fp->f_lock);
- if (--fp->f_count == 0) { /* last reference */
- pthread_mutex_unlock(&fp->f_lock);
- pthread_mutex_destroy(&fp->f_lock);
- free(fp);
- } else {
- pthread_mutex_unlock(&fp->f_lock);
- }
- }
- void *thr_fn1(void *pp){
- struct foo *p=(struct foo *)pp;
- printf("thread 1.......\n");
- foo_hold(p);
- pthread_exit((void*)1);
- }
- void *thr_fn2(void *pp){
- struct foo *p=(struct foo *)pp;
- printf("thread 2.......\n");
- foo_hold(p);
- pthread_exit((void*)2);
- }
- int
- main(){
- pthread_t tid1,tid2;
- void * ret1,*ret2;
- struct foo *pf;
- pf = foo_alloc();
- if(!pf)
- exit(-1);
- pthread_create(&tid1,NULL,thr_fn1,(void *)pf);
- pthread_join(tid1,&ret1);
- printf("main 1 : %d --\n",pf->f_count);
- pthread_create(&tid2,NULL,thr_fn2,(void *)pf);
- printf("main 2 : %d --\n",pf->f_count);
- pthread_join(tid2,&ret2);
- printf("main 3 : %d --\n",pf->f_count);
- }
程序清单11-6 使用两个相互排斥量
- #include <stdlib.h>
- #include <pthread.h>
- #define NHASH 29
- #define HASH(fp) (((unsigned long)fp)%NHASH)
- struct foo *fh[NHASH];
- pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER;
- struct foo {
- int f_count;
- pthread_mutex_t f_lock;
- struct foo *f_next; /* protected by hashlock */
- int f_id;
- /* ... more stuff here ... */
- };
- struct foo *
- foo_alloc(void) /* allocate the object */
- {
- struct foo *fp;
- int idx;
- if ((fp = malloc(sizeof(struct foo))) != NULL) {
- fp->f_count = 1;
- if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
- free(fp);
- return(NULL);
- }
- idx = HASH(fp);
- pthread_mutex_lock(&hashlock);
- fp->f_next = fh[idx];
- fh[idx] = fp->f_next;
- pthread_mutex_lock(&fp->f_lock);
- pthread_mutex_unlock(&hashlock);
- /* ... continue initialization ... */
- thread_mutex_unlock(&fp->f_lock);
- }
- return(fp);
- }
- void
- foo_hold(struct foo *fp) /* add a reference to the object */
- {
- pthread_mutex_lock(&fp->f_lock);
- fp->f_count++;
- pthread_mutex_unlock(&fp->f_lock);
- }
- struct foo *
- foo_find(int id) /* find an existing object */
- {
- struct foo *fp;
- int idx;
- idx = HASH(fp);
- pthread_mutex_lock(&hashlock);
- for (fp = fh[idx]; fp != NULL; fp = fp->f_next) {
- if (fp->f_id == id) {
- foo_hold(fp);
- break;
- }
- }
- pthread_mutex_unlock(&hashlock);
- return(fp);
- }
- void
- foo_rele(struct foo *fp) /* release a reference to the object */
- {
- struct foo *tfp;
- int idx;
- pthread_mutex_lock(&fp->f_lock);
- if (fp->f_count == 1) { /* last reference */
- pthread_mutex_unlock(&fp->f_lock);
- pthread_mutex_lock(&hashlock);
- pthread_mutex_lock(&fp->f_lock);
- /* need to recheck the condition */
- if (fp->f_count != 1) {
- fp->f_count--;
- pthread_mutex_unlock(&fp->f_lock);
- pthread_mutex_unlock(&hashlock);
- return;
- }
- /* remove from list */
- idx = HASH(fp);
- tfp = fh[idx];
- if (tfp == fp) {
- fh[idx] = fp->f_next;
- } else {
- while (tfp->f_next != fp)
- tfp = tfp->f_next;
- tfp->f_next = fp->f_next;
- }
- pthread_mutex_unlock(&hashlock);
- pthread_mutex_unlock(&fp->f_lock);
- pthread_mutex_destroy(&fp->f_lock);
- free(fp);
- } else {
- fp->f_count--;
- pthread_mutex_unlock(&fp->f_lock);
- }
- }
程序清单11-7 简化的加,解锁
- #include <stdlib.h>
- #include <pthread.h>
- #define NHASH 29
- #define HASH(fp) (((unsigned long)fp)%NHASH)
- struct foo *fh[NHASH];
- pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER;
- struct foo {
- int f_count; /* protected by hashlock */
- pthread_mutex_t f_lock;
- struct foo *f_next; /* protected by hashlock */
- int f_id;
- /* ... more stuff here ... */
- };
- struct foo *
- foo_alloc(void) /* allocate the object */
- {
- struct foo *fp;
- int idx;
- if ((fp = malloc(sizeof(struct foo))) != NULL) {
- fp->f_count = 1;
- if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
- free(fp);
- return NULL;
- }
- idx = HASH(fp);
- pthread_mutex_lock(&hashlock);
- fp->f_next = fh[idx];
- fh[idx] = fp;
- pthread_mutex_lock(&fp->f_lock); // Why ?
- ??
- pthread_mutex_unlock(&hashlock);
- /* ... continue initialization ... */
- }
- return fp;
- }
- void
- foo_hold(struct foo *fp) /* add a reference to the object */
- {
- pthread_mutex_lock(&hashlock);
- fp->f_count++;
- pthread_mutex_unlock(&hashlock);
- }
- struct foo *
- foo_find(int id) /* find an existing object */
- {
- struct foo *fp;
- int idx;
- idx = HASH(fp);
- pthread_mutex_lock(&hashlock);
- for (fp = fh[idx]; fp != NULL; fp = fp->f_next) {
- if (fp->f_id == id) {
- fp->f_count++;
- break;
- }
- }
- pthread_mutex_unlock(&hashlock);
- return fp;
- }
- void
- foo_rele(struct foo *fp) /* release a reference to the object */
- {
- struct foo *tfp;
- int idx;
- pthread_mutex_lock(&hashlock);
- if (--fp->f_count == 0) { /* last reference, remove from list */
- idx = HASH(fp);
- tfp = fh[idx];
- if (tfp == fp) {
- fh[idx] = fp->f_next;
- } else {
- while (tfp->f_next != fp)
- tfp = tfp->f_next;
- tfp->f_next = fp->f_next;
- }
- pthread_mutex_unlock(&hashlock);
- pthread_mutex_destroy(&fp->f_lock);
- free(fp);
- } else {
- pthread_mutex_unlock(&hashlock);
- }
- }
程序清单11-8 使用读写锁
- #include <stdlib.h>
- #include <pthread.h>
- struct job {
- struct job *j_next;
- struct job *j_prev;
- pthread_t j_id; /* tells which thread handles this job */
- /* ... more stuff here ... */
- };
- struct queue {
- struct job *q_head;
- struct job *q_tail;
- pthread_rwlock_t q_lock;
- };
- /*
- * Initialize a queue.
- */
- int
- queue_init(struct queue *qp)
- {
- int err;
- qp->q_head = NULL;
- qp->q_tail = NULL;
- err = pthread_rwlock_init(&qp->q_lock, NULL);
- if (err != 0)
- return err;
- /* ... continue initialization ... */
- return 0;
- }
- /*
- * Insert a job at the head of the 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; /* list was empty */
- qp->q_head = jp;
- pthread_rwlock_unlock(&qp->q_lock);
- }
- /*
- * Append a job on the tail of the 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; /* list was empty */
- qp->q_tail = jp;
- pthread_rwlock_unlock(&qp->q_lock);
- }
- /*
- * Remove the given job from a queue.
- */
- void
- job_remove(struct queue *qp, struct job *jp)
- {
- pthread_rwlock_wrlock(&qp->q_lock);
- if (jp == qp->q_head) {
- qp->q_head = jp->j_next;
- if (qp->q_tail == jp)
- qp->q_tail = NULL;
- } else if (jp == qp->q_tail) {
- qp->q_tail = jp->j_prev;
- if (qp->q_head == jp)
- qp->q_head = NULL;
- } else {
- jp->j_prev->j_next = jp->j_next;
- jp->j_next->j_prev = jp->j_prev;
- }
- pthread_rwlock_unlock(&qp->q_lock);
- }
- /*
- * Find a job for the given thread ID.
- */
- struct job *
- job_find(struct queue *qp, pthread_t id)
- {
- struct job *jp;
- if (pthread_rwlock_rdlock(&qp->q_lock) != 0)
- return NULL;
- for (jp = qp->q_head; jp != NULL; jp = jp->j_next)
- if (pthread_equal(jp->j_id, id))
- break;
- pthread_rwlock_unlock(&qp->q_lock);
- return jp;
- }
程序清单11-9 使用条件变量
- #include <pthread.h>
- struct msg {
- struct msg *m_next;
- /* ... more stuff ... */
- };
- struct msg *workq;
- pthread_cond_t qready = PTHREAD_COND_INITIALIZER;
- pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;
- void
- process_msg(void)
- {
- struct msg *mp;
- for (;;) {
- pthread_mutex_lock(&qlock);
- while (workq == NULL)
- pthread_cond_wait(&qready, &qlock);
- mp = workq;
- workq = mp->m_next;
- pthread_mutex_unlock(&qlock);
- /* now process the message mp */
- }
- }
- void
- enqueue_msg(struct msg *mp)
- {
- pthread_mutex_lock(&qlock);
- mp->m_next = workq;
- workq = mp;
- pthread_mutex_unlock(&qlock);
- pthread_cond_signal(&qready);
- }
APUE 线程 - 程序清单的更多相关文章
- APUE信号-程序汇总
APUE信号-程序汇总 近期重看APUE,发现对于非常多程序的要领还是没有全然理解.所以梳理下便于查看,并且有非常多值得思考的问题. 程序清单10- 1 捕获 SIGUSR1 和 SIGU ...
- 程序清单 8-8 exec函数实例,a.out是程序8-9产生的可执行程序
/* ============================================================================ Name : test.c Author ...
- 程序清单8-3 8-4 演示不同的exit值
//http://blog.chinaunix.net/uid-24549279-id-71355.html /* ========================================== ...
- windows phone 8 开发系列(三)程序清单说明与配置
一 清单文件内容介绍 当我们先建了一个项目之后,我们可以看到vs自动会为我们创建了很多文件,正常人都会先一个个去翻看下每个文件都是干啥的,都主要写了些啥,在这些文件中,在Properies目录下面,我 ...
- [C++ Primer Plus] 第11章、使用类(一)程序清单——重载 P408
程序清单11.4~11.6(运算符重载——添加加法运算符) //1.h class Time { private: int hours; int minutes; public: Time(); Ti ...
- [C++ Primer Plus] 第10章、对象和类(一)程序清单——辨析三个const
程序清单10.1+10.2+10.3 头文件stock.h #ifndef STOCK00_H_ //先测试x是否被宏定义过 #define STOCK00_H_ //如果没有宏定义,就宏定义x并编译 ...
- [C++ Primer Plus] 第9章、内存模型和名称空间(一)程序清单
程序清单9.9(静态存储连续性.无链接性) #include<iostream> using namespace std; ; void strcount(const char *str) ...
- [C++ Primer Plus] 第8章、函数探幽(一)程序清单——内联、引用、格式化输入输出、模板、decltype
程序清单8.1(inline内联函数) #include<iostream> using namespace std; inline double square(double x) {// ...
- [C++ Primer Plus] 第7章、函数(一)程序清单——递归,指针和const,指针数组和数组指针,函数和二维数组
程序清单7.6 #include<iostream> using namespace std; ; int sum_arr(int arr[], int n);//函数声明 void ma ...
随机推荐
- 第4节 hive调优:动态分区调整问题
执行如下截图中的语句时卡住了: 原因:yarn未启动,hive底层是要提交mapreduce到yarn上才能计算结果的. 之前启动yarn时,未执行jps查看是否已经启动.其实未启动成功: [root ...
- Maven实战读书笔记(二):Maven坐标与仓库
2.1 Maven坐标 Maven坐标是Maven用来表示一个组件依赖的标示. Maven通过下面几个元素定义坐标:groupId.artifactId.version.packaging.class ...
- ICPC-Beijing 2006 狼抓兔子
题目描述 题解: 裸的最小割. 但是最大流跑不过去怎么办? 转变一下,既然最大流是一条左下<->右上的通路,我们可以把图划分为若干区域, 最后找左下到右上的最短路就行了. 代码: #inc ...
- MySQL redo log 与 binlog 的区别
MySQL redo log 与 binlog 的区别 什么是redo log 什么是binlog redo log与binlog的区别 1. 什么是redo log? redo log又称重做日志文 ...
- InnoDB体系架构总结(一)
缓冲池: 是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库性能的影响.在数据库中读取的页数据会存放到缓冲池中,下次再读取相同页的时候,会首先判断该页是否在缓冲池中.对于数据库中页的修改操 ...
- 官网Android离线文档下载
这是Android的离线API及一些Guide——俗称的/docs文件夹下的内容——英文版的...——http://pan.baidu.com/s/1qXmLlQc
- POJ 2251-Dungeon Master (三维空间求最短路径)
Description You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is co ...
- fstream,sstream的学习记录
fstream: #include<iostream> #include<fstream> using namespace std; int main(){ ofstream ...
- You Are the One (区间DP)
The TV shows such as You Are the One has been very popular. In order to meet the need of boys who ar ...
- POJ-3468A Simple Problem with Integers,线段数区间更新查询,代码打了无数次还是会出错~~
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Case Time L ...