- 浏览: 61680 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
brxonline:
提示不能这样写234390216 写道234390216 写道 ...
mysql导出数据为excel -
234390216:
234390216 写道不行啊,错误
提示不能这样写
mysql导出数据为excel -
234390216:
不行啊,错误
mysql导出数据为excel
1.线程标识
每个线程都有一个线程ID,线程ID只在它所属的进程环境有效
线程ID比较函数
#include <pthread.h> int pthread_equal(pthread_t tid1, pthread_t tid2);
|
Returns: nonzero if equal, 0 otherwise |
线程获得自身ID函数
#include <pthread.h> pthread_t pthread_self(void);
|
Returns: the thread ID of the calling thread |
2.线程创建
#include <pthread.h> int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrictattr, void *(*start_rtn)(void), void *restrict arg);
|
Returns: 0 if OK, error number on failure |
当pthread_create成功返回时,由tidp指向的内存单元被设置为新创建线程的线程ID,新创建的线程从start_rtn函数的地址开始运行
例:打印线程ID
#include "apue.h" #include <pthread.h> pthread_t ntid; void printids(const char *s) { pid_t pid; pthread_t tid; pid = getpid(); tid = pthread_self(); 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); }
3.线程终止
单个线程可以通过下列三种方式退出
1)线程只是从启动例程中返回,返回值是线程的退出码
2)线程可以被同一进程中的其他线程取消
3)线程调用pthread_exit
#include <pthread.h>
void pthread_exit(void *rval_ptr);
|
rval_ptr ,进程中的其他线程可以通过调用pthread_join函数访问到这个指针
#include <pthread.h> int pthread_join(pthread_t thread, void **rval_ptr);
|
Returns: 0 if OK, error number on failure |
调用pthread_join的线程将一直阻塞,直到指定的线程调用pthread_exit、从启动例程中返回或者被取消。
例:获得线程退出状态
#include "apue.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); }
线程可以通过调用pthread_cancel函数来请求取消同一进程中的其他线程,只是发出请求,不是终止
#include <pthread.h>
int pthread_cancel(pthread_t tid);
|
Returns: 0 if OK, error number on failure |
线程可以安排它退出时需要调用的函数
#include <pthread.h> void pthread_cleanup_push(void (*rtn)(void *), void *arg); void pthread_cleanup_pop(int execute);
线程执行以下动作时调用清理函数
1)调用pthread_exit
2)响应取消请求
3)用非0execute参数调用 pthread_cleanup_pop时
例:线程清理处理程序
#include "apue.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); }
使用pthread_detach调用可以用于使线程进入分离状态(另外一种方式是修改创建进程时的属性)
#include <pthread.h>
int pthread_detach(pthread_t tid);
|
Returns: 0 if OK, error number on failure |
4.线程同步
1)互斥量
#include <pthread.h> int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); int pthread_mutex_destroy(pthread_mutex_t *mutex);
|
Both return: 0 if OK, error number on failure |
#include <pthread.h> int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex);
|
All return: 0 if OK, error number on failure |
例:使用互斥量的数据结构
#include <stdlib.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); } }
例:避免死锁
#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->f_next; pthread_mutex_lock(&fp->f_lock); 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 a 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); } }
2)读写锁
#include <pthread.h> int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
|
Both return: 0 if OK, error number on failure |
#include <pthread.h> int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
|
All return: 0 if OK, error number on failure |
#include <pthread.h> int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
|
Both return: 0 if OK, error number on failure |
例:使用读写锁
#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); }
3)条件变量
#include <pthread.h> int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t *restrict attr); int pthread_cond_destroy(pthread_cond_t *cond);
|
Both return: 0 if OK, error number on failure |
#include <pthread.h> int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex); int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict timeout);
|
Both return: 0 if OK, error number on failure |
例:使用条件变量
#include <pthread.h> struct msg { struct msg *m_next; /* ... more stuff here ... */ }; 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); }
发表评论
-
UNIX网络编程(1)-简介
2011-10-06 17:31 7541.bzero函数 bzero 等同于memset(void ... -
UNIX编程(15)-进程间通信
2011-08-07 12:09 1085. 管道 #include <un ... -
UNIX编程(14)-高级IO
2011-08-03 21:36 13781.非阻塞IO 对于一个给定的描述符有两种方法对其指定非阻塞 ... -
UNIX编程(13)-守护进程
2011-08-02 21:59 9251.守护进程的编程规则 1)用umask将文件模式创建屏蔽字 ... -
UNIX编程(12)-线程控制
2011-07-27 15:26 9121.线程限制 某些系统有线程的限制,可以通过sysconf函 ... -
UNIX编程(10)-信号
2011-07-20 21:18 9741.signal函数 #include ... -
UNIX编程(9)-进程关系
2011-07-12 14:41 11061.终端登录 2.网络登录 3.进程组 ... -
UNIX编程(8)-进程控制
2011-07-09 11:37 11631.进程标识符 每个进程 ... -
UNIX编程(7)-进程环境
2011-07-01 15:07 8691.main 函数 c程序总是从main函数开始执行,当内核 ... -
UNIX编程(6)-系统数据文件和信息
2011-06-28 16:35 11701.口令文件 口令文件存储在/etc/passwd中,是一个A ... -
UNIX编程(5)-标准IO库
2011-06-27 16:55 9201.流的定向 freopen函数清 ... -
UNIX编程(4)-文件和目录
2011-06-23 16:56 12471.stat,fstat,lstat函数 #include & ... -
UNIX编程(3)-文件IO
2011-06-21 17:45 14121.open函数 #include <fcntl.h&g ... -
UNIX编程(2)-UNIX标准化
2011-06-15 11:41 6761.ISO c 2.IEEE POSIX 3.Single U ... -
UNIX编程(1)-基础知识
2011-06-15 10:54 8081.登陆名 登陆名放在/etc ...
相关推荐
下载于北大未名BBS精华区 内容:UNIX环境高级编程,Linux网络编程,Linux编程杂项,Linux窗口编程,Linux多线程编程,Linux脚本编程
《Unix环境高级编程》第十二章——线程控制PPT
多线程编程UNIXLinux下的多线程编程.pdf
。。。
。。。
UNIX系统编程 PDF part2 不错的一本UNIX 系统编程书籍
本书是UNIX系统编程的经典教材,并基于最新的UNIX标准进行了更新,其内容完全覆盖文件、信号、POSIX线程、UDP、Web和客户机-服务器等相关内容,并对通信、并发和多线程问题进行了透彻的研究,对复杂的概念进行了...
主要根据本人在UNIX系统上的编程实践经验总结而成, 既做为自己在 一个时期内编程实践的部分总结, 又可成为文章发表. 对UNIX程序员初学者来 说是一个小小的经验, 仅供参考; 对UNIX老手来说则不值一提。 。 6.wait...
该《多线程编程指南》基于POSIX 标准IEEE Std 1003.1 1996 版(又称作ISO/IEC 9945–1 第二版)。最新修订版的POSIX 标准IEEE Std 1003.1:2001(又称作ISO/IEC 9945:2002 和单一UNIX 规范版本3)中也提供了这些功能...
unix环境下的线程库实现,包含若干个重要函数,是大学学习unix环境高级编程必备的题目。
包含详细介绍多线程编程的四个文档及可运行的代码: 1、多线程编程-API.doc 2、多线程编程-互斥锁.doc 3、多线程编程-信号量.doc 4、多线程编程-监控线程.doc 其中监控线程部分有较好的参考价值。
本书是被誉为UNIX编程“圣经”的Advanced Programming in the UNIX Environment一书的更新版。在本书第1版出版后的十几年中,UNIX行业已经有了巨大的变化,特别是影响UNIX编程接口的有关标准变化很大。本书在保持了...
本书是UNIX系统编程的经典教材,是基于最新UNIX标准的参考书,对UNIX编程本质进行了清晰透乇的介绍。本书完全覆盖文件、信号、信号量、 POSIX线程以及客户端一服务器通信等内容,对通信、并发和多线程问题进行了深入...
《linux/unix系统编程手册(上、下册)》是介绍linux与unix编程接口的权威著作。linux编程资深专家michael kerrisk在书中详细描述了linux/unix系统编程所涉及的系统调用和库函数,并辅之以全面而清晰的代码示例。...
学习笔记多线程Unix编程
本书是UNIX系统编程的经典教材,是基于最新UNIX标准的参考书,对UNIX编程本质进行了清晰透乇的介绍。本书完全覆盖文件、信号、信号量、 POSIX线程以及客户端一服务器通信等内容,对通信、并发和多线程问题进行了深入...
unix多线程和多进程同步技术概要,笼罩了常见的unix多线程和多进程函数,还有详细文字介绍。
本书是被誉为UNIX编程“圣经”的Advanced Programming in the UNIX Environment一书的更新版。书中除了介绍UNIX文件和目录、标准I/O库、系统数据文件和信息、进程环境、进程控制、进程关系、信号、线程、线程控制、...
详细讲解了linux/unix的多线程的原理,编程方法,线程结构等等,一步一步教你进行多线程的编程。
统中才引入多线程机制,如今,由于自身的许多优点,多线程编程已经得到了广泛的应用。 本文我们将介绍在Linux 下编写多进程和多线程程序的一些初步知识。 1 引言 对于没有接触过 Unix/Linux 操作系统的人来说,fork ...