- 浏览: 65024 次
- 性别:
- 来自: 苏州
-
文章分类
最新评论
-
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 *restrict
|
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
|
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
|
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
|
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
|
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
|
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 8201.bzero函数 bzero 等同于memset(void ... -
UNIX编程(15)-进程间通信
2011-08-07 12:09 1135. 管道 #include <un ... -
UNIX编程(14)-高级IO
2011-08-03 21:36 14291.非阻塞IO 对于一个给定的描述符有两种方法对其指定非阻塞 ... -
UNIX编程(13)-守护进程
2011-08-02 21:59 9701.守护进程的编程规则 1)用umask将文件模式创建屏蔽字 ... -
UNIX编程(12)-线程控制
2011-07-27 15:26 9541.线程限制 某些系统有线程的限制,可以通过sysconf函 ... -
UNIX编程(10)-信号
2011-07-20 21:18 10471.signal函数 #include ... -
UNIX编程(9)-进程关系
2011-07-12 14:41 11611.终端登录 2.网络登录 3.进程组 ... -
UNIX编程(8)-进程控制
2011-07-09 11:37 12281.进程标识符 每个进程 ... -
UNIX编程(7)-进程环境
2011-07-01 15:07 9151.main 函数 c程序总是从main函数开始执行,当内核 ... -
UNIX编程(6)-系统数据文件和信息
2011-06-28 16:35 12121.口令文件 口令文件存储在/etc/passwd中,是一个A ... -
UNIX编程(5)-标准IO库
2011-06-27 16:55 9861.流的定向 freopen函数清 ... -
UNIX编程(4)-文件和目录
2011-06-23 16:56 12891.stat,fstat,lstat函数 #include & ... -
UNIX编程(3)-文件IO
2011-06-21 17:45 14751.open函数 #include <fcntl.h&g ... -
UNIX编程(2)-UNIX标准化
2011-06-15 11:41 7261.ISO c 2.IEEE POSIX 3.Single U ... -
UNIX编程(1)-基础知识
2011-06-15 10:54 8441.登陆名 登陆名放在/etc ...
相关推荐
根据提供的信息,我们可以了解到这是一本关于《UNIX编程艺术》的经典书籍,该书提供了高清扫描版本,并且包含完整的书签,方便读者进行阅读与查阅。接下来,我们将从这本书的主题出发,探讨几个重要的UNIX编程概念与...
Unix-Linux-Windows-OpenMP 多线程编程知识点总结 POSIX 的基本知识 POSIX(Portable Operating System Interface)是一种可移植操作系统接口标准,旨在提供源代码级的软件可移植性。POSIX 标准定义了操作系统应该...
Unix-Linux-Windows-OpenMP 多线程编程 本文档主要介绍 Unix/Linux 多线程编程接口及编程技术,重点讲解 POSIX 的一些基本知识。POSIX 是可移植操作系统接口(Portable Operating System Interface)的首字母缩写,...
本资料集专注于"Linux编程技术-多线程-网络编程",它涵盖了UNIX环境高级编程、Linux网络编程、Linux多线程编程、Linux窗口编程以及Linux脚本编程等多个核心主题。这些内容都是构建高效、可靠且可扩展的Linux应用的...
在类Unix系统中,早期并没有线程的概念,大约是在80年代才引入了这个概念。因此,线程在这些系统中通常是通过进程机制来实现的。 1. **轻量级进程**(LWP):具有自己的PCB,创建线程时使用的底层函数与创建进程时...
通过学习《UNIX高级编程》,程序员不仅可以掌握UNIX编程的核心技术,还能培养出系统级别的思维,从而能够设计和编写更高效、更稳定、更健壮的软件系统。无论是对初学者还是经验丰富的开发者,这都是一本极具价值的...
《UNIX网络编程——第一卷——套接口API》是网络编程领域的经典之作,尤其在UNIX操作系统环境下,这本书被视为不可或缺的学习资源。作者深入浅出地讲解了网络通信的基础理论和实际操作,帮助开发者理解如何利用套...
- **POSIX标准**:提供了跨平台的UNIX编程接口,如pthread库用于线程编程。 通过深入学习和实践以上知识点,你将能够熟练地进行UNIX系统编程,开发出高效、稳定的应用程序。记得结合《UNIX系统编程》这样的参考...
《UNIX环境高级编程》是一本深受程序员和系统管理员喜爱的经典之作,主要针对那些希望深入理解UNIX操作系统,并能熟练进行...无论是自学还是作为参考手册,这本书及其相关资料都能为你的UNIX编程之路提供强大的支持。
《UNIX网络编程-第2卷-进程间通讯》是一本深入探讨UNIX系统中进程间通信(Inter-Process Communication, IPC)的经典著作。该书详细阐述了如何在多进程环境中实现有效的数据交换,这对于理解操作系统原理、开发高效...
《Unix编程艺术》、《Unix环境高级编程(第二版)》和《Unix网络编程(第二版)》是三本在IT领域中具有深远影响力的经典著作,涵盖了Unix操作系统的核心概念、系统调用、进程管理、文件操作、网络通信等多个重要主题...
UNIX系统以其稳定、高效和强大的命令行接口而著名,对于系统管理员和高级程序员来说,深入理解和掌握UNIX的高级编程技巧至关重要。"UNIX高级编程18-20(大师著作)"这部分内容可能涵盖了以下几个关键知识点: 1. **...
《Linux/UNIX网络编程》是甘刚教授撰写的一本深入探讨网络编程技术的专业书籍,主要针对使用Linux和UNIX操作系统进行网络应用开发的程序员。这本书详细介绍了如何在这些系统上构建网络应用程序,涵盖了从基础概念到...
在Unix环境中,线程控制是高级编程中的一个重要概念,它涉及到多线程程序的设计和管理。线程控制允许程序员在单个进程中同时执行多个独立的执行流,从而提高程序的并发性和效率。以下是对《Unix环境高级编程》第十二...
《QNX-UNIX-POSIX-C函数手册》是一份针对编程初学者的宝贵资源,尤其适合那些在Linux环境中使用C语言进行开发的程序员。这份手册详细介绍了C语言标准库以及与QNX、UNIX和POSIX操作系统相关的扩展函数,旨在帮助...
1. **多线程和多进程支持**:HP-UNIX支持多线程和多进程并发执行,使得系统能够高效地处理多个任务,提升整体工作效率。 2. **高级内存管理**:具备先进的内存分配和回收机制,确保系统的稳定运行,减少因内存泄露...
根据提供的标题“Unix编程艺术中文版(非加密,带目录)”及描述“Unix编程艺术中文版”,可以推测这是一本介绍Unix系统编程原理、技巧和最佳实践的书籍。本书可能涵盖Unix系统的背景知识、核心概念、编程工具和技术...
10. **POSIX线程(pthread)编程**:介绍多线程的概念,线程创建(pthread_create())、同步(pthread_mutex_t, pthread_cond_t等)和线程属性设置。 通过实践这些示例代码,开发者不仅可以了解UNIX系统的底层工作...
"UNIX高级编程21-23(大师著作)"这个压缩包文件包含了三部分关于这一主题的深度学习资料,分别命名为022.PDF、021.PDF、023.PDF,这些PDF文件很可能是从一本经典的UNIX编程书籍中提取的章节。 UNIX高级编程涵盖了...
### 多线程编程在UNIX/Linux环境中的应用与优势 多线程编程作为一种高效的数据处理方式,在UNIX/Linux环境下得到了广泛的应用。与传统的单线程进程相比,多线程编程能够显著提升程序的性能和响应速度,尤其是在现代...