APUE 线程 - 程序清单
来源:互联网 发布:java开发实战经典下载 编辑:程序博客网 时间:2024/05/21 17:57
APUE 线程 - 程序清单
程序清单11-1 打印线程ID
程序清单11-2 获得线程退出状态
程序清单11-3 pthread_exit 的参数不正确使用
程序清单11-4 线程清理处理程序
程序清单11-5 使用互斥量保护数据结构
程序清单11-6 使用两个互斥量
程序清单11-7 简化的加,解锁
程序清单11-8 使用读写锁
程序清单11-1 打印线程ID
#include "util.h"#include<pthread.h>pthread_t ntid;voidprintids(const char *s){pid_tpid;pthread_ttid;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);}intmain(void){interr;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);}intmain(void){interr;pthread_ttid1, 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;};voidprintfoo(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 foofoo = {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);}intmain(void){interr;pthread_ttid1, 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>voidcleanup(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);}intmain(void){interr;pthread_ttid1, 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);}voidfoo_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);}voidfoo_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;intidx;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);}voidfoo_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;intidx;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);}voidfoo_rele(struct foo *fp) /* release a reference to the object */{struct foo*tfp;intidx;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;}voidfoo_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;}voidfoo_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. */intqueue_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. */voidjob_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. */voidjob_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. */voidjob_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;voidprocess_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 */ }}voidenqueue_msg(struct msg *mp){ pthread_mutex_lock(&qlock); mp->m_next = workq; workq = mp; pthread_mutex_unlock(&qlock); pthread_cond_signal(&qready);}
0 0
- APUE 线程 - 程序清单
- apue程序清单3-1
- APUE程序清单4-7编译错误:path_alloc未定义
- 关于APUE 程序清单8-5的理解
- APUE 程序清单10-11 信号设置和sigprocmask实例
- APUE.2e程序清单4-7举例分析
- APUE.2e程序清单4-7举例分析
- apue程序清单10_6中信号处理程序提早终止的问题
- APUE线程
- ~分析apue程序清单4-7 递归降序遍历目录层次结构,并按文件类型计数 。
- APUE: 12-2程序清单 使用递归锁 处:能不能不用递归锁? P321
- APUE-- 线程编程
- APUE学习 线程控制
- [APUE]第十一章 线程
- apue线程学习
- [APUE] 线程和fork
- APUE线程控制
- [APUE] 线程池
- 设计模式观后(c++还原之二十四 解释器模式)
- YARN与MapReduce
- 动态编译.java文件
- #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
- 黑马程序猿——深入理解什么是反射
- APUE 线程 - 程序清单
- POJ 2828 线段树单点更新 离线搞
- OpenCV入门(三)复杂一点的变换
- CODE[VS]_1214 线段覆盖问题
- CH Round #55 - Streaming #6 (NOIP模拟赛day2)总结
- ie6下的兼容性问题
- POJ 3268 双向Dijkstra
- Linux makefile 教程 非常详细,且易懂
- 【Java.Web】JSP —— 语法基础 —— 包含include