第十二章 线程控制
来源:互联网 发布:javascript编程题目 编辑:程序博客网 时间:2024/06/05 07:35
1. 线程属性
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);
int pthread_attr_getdetachstate(const pthread_attr_t *restrict attr, int *detachstate); //获取当前的detachstate线程属性
int pthread_attr_setdetachstate(pthread_attr_t *restrict attr, int *detachstate);
//当detachstate为PTHREAD_CREATE_DETACHED时,以分离状态启动线程;
//当detachstate为PTHREAD_CREATE_JOINABLE时,正常启动线程,应用程序可以获取线程的终止状态
#include "apue.h"#include <pthread.h>int makethread(void *(*fn)(void *), void *arg){int err;pthread_t tid;pthread_attr_t attr;err = pthread_attr_init(&attr);if(err != 0)return err;err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);if(err == 0)err = pthread_create(&tid, &attr, fn, arg);pthread_attr_destroy(&attr);return err;}
对线程栈的属性更改
int pthread_attr_getstack(const pthread_attr_t *restrict attr, void **restrict stackaddr, size_t *restrict stacksize);
int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize);
设置线程属性stacksize
int pthread_attr_getstacksize(const pthread_attr_t *restrict attr, size_t *restrict stacksize);
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
线程属性guardsize控制着线程栈末尾之后用以避免栈溢出的扩展内存的大小。
int pthread_attr_getguardsize(const pthread_attr_t *restrict attr, size_t *restrict guardsize);
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
2. 同步属性
i. 互斥量属性
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
int pthread_mutexattr_getshared(const pthread_mutex_attr_t *restrict attr, int *restrict pshared); //得到它的进程共享属性
int pthread_mutexattr_setshared(pthread_mutexattr_t *attr, int pshared); //修改进程共享属性
递归互斥量..
ii. 读写锁属性
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
读写锁支持的唯一属性是进程共享属性。
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr, int *restrict pshared);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared);
iii. 条件变量属性(进程共享属性和时钟属性)
iX. 屏障属性(进程共享属性)
3. 线程特定数据
在分配线程特定数据之前,需要创建与该数据关联的键。
int pthread_key_create(pthread_key_t *keyp, void (*destructor)(void *));
取消键与线程特定数据值之间的关联关系
int pthread_key_delete(pthread_key_t key);
4. 线程和信号
int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
int sigwait(const sigset_t *restrict set, int *restrict signop);//等待一个或者多个信号的出现
int pthread_kill(pthread_t thread, int signo);
#include "apue.h"#include <pthread.h>int quitflag;sigset_t mask;pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t waitloc = PTHREAD_COND_INITIALIZER;void *thr_fn(void *arg){int err, signo;for(;;){err = sigwait(&mask, &signo);if(err != 0)err_exit(err, "sigwait failed");switch(signo){case SIGINT:printf("\ninterrupt\n");break;case SIGQUIT:pthread_mutex_lock(&lock);quitflag = 1;pthread_mutex_unlock(&lock);pthread_cond_signal(&waitloc);return 0;default:printf("unexpected signal %d\n", signo);exit(1);}}}int main(void){int err;sigset_t oldmask;pthread_t tid;sigemptyset(&mask);sigaddset(&mask, SIGINT);sigaddset(&mask, SIGQUIT);if((err = pthread_sigmask(SIG_BLOCK, &mask, &oldmask)) != 0)err_exit(err, "SIG_BLOCK error");err = pthread_create(&tid, NULL, thr_fn, 0);if(err != 0)err_exit(err, "can't create thread");pthread_mutex_lock(&lock);while(quitflag == 0)pthread_cond_wait(&waitloc, &lock);pthread_mutex_unlock(&lock);quitflag = 0;if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)err_sys("SIG_SETMASK error");exit(0);}
5. 线程和fork
多线程中清除锁的状态
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
#include "apue.h"#include <pthread.h>pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;void prepare(void){int err;printf("prepare locks...\n");if((err = pthread_mutex_lock(&lock1)) != 0)err_cont(err, "can't lock lock1 in prepare handler");if((err = pthread_mutex_lock(&lock2)) != 0)err_cont(err, "can't lock lock2 in prepare handler");}void parent(void){int err;printf("parent unlocking locks...\n");if((err = pthread_mutex_unlock(&lock1)) != 0)err_cont(err, "can't unlock lock1 in parent handler");if((err = pthread_mutex_unlock(&lock2)) != 0)err_cont(err, "can't unlock lock2 in parent handler");}void child(void){int err;printf("child unlocking locks...\n");if((err = pthread_mutex_unlock(&lock1)) != 0)err_cont(err, "can't unlock lock1 in parent handler");if((err = pthread_mutex_unlock(&lock2)) != 0)err_cont(err, "can't unlock lock2 in parent handler");}void *thr_fn(void *arg){printf("thread started...\n");pause();return 0;}int main(void){int err;pid_t pid;pthread_t tid;if((err = pthread_atfork(prepare, parent, child)) != 0)err_exit(err, "can't install fork handlers");if((err = pthread_create(&tid, NULL, thr_fn, 0)) != 0)err_exit(err, "can't create thread");sleep(2);printf("parent about to fork\n");if((pid = fork()) < 0)err_quit("fork failed");else if(pid == 0)printf("child returned from fork\n");elseprintf("parent returned from fork\n");exit(0);}/************************thread started...parent about to forkprepare locks...parent unlocking locks...parent returned from forkchild unlocking locks...child returned from fork************************/书上的结果是子进程先解锁,然后再是父进程(???)
- 第十二章 线程控制
- [APUE]第十二章 线程控制
- apue 第十二章 线程控制
- AUPE学习第十二章------线程控制
- APUE读书笔记-第十二章 线程控制
- 《APUE》笔记-第十二章-线程控制
- 《APUE》读书笔记—第十二章线程控制
- APUE读书笔记-第十二章-线程控制
- APUE学习笔记——第十二章 线程控制
- apue学习笔记(第十二章 线程控制)
- UNIX环境高级编程第十二章 线程控制 总结
- 第十二章 POSIX线程
- 第十二章 线程
- 第十二章 POSIX线程
- UNIX环境高级编程学习之第十二章线程控制-以分离状态创建线程
- 人工智能:第十二章 智能控制
- 第十二章 内存控制块
- unix高级环境编程 例子 代码实现练习 第十二章:线程控制
- mysql中日期比较大小方法详解
- 【jzoj4630】【计数】【数位动态规划】
- 剑指offer面试题22:栈的压入、弹出序列
- 飞思卡尔IMX6修改uboot默认启动参数
- pop 到指定vc
- 第十二章 线程控制
- unity3d TextMesh清晰字体
- 区块链技术原理
- nginx在mac中的配置
- 执笔微小说之单爱
- Eclipse的Servers视图中无法添加Tomcat7
- Java对象创建过程
- 圆角矩形的UIButton
- R-CNN 学习笔记