狐狸梦见乌鸦

当坚持成为一种习惯,目标将不在遥远```
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

线程学习笔记

Posted on 2012-01-04 19:13  灬啊U  阅读(186)  评论(0编辑  收藏  举报
2012.1.4 进程复习: 1. 创建 fork 2. 退出 exit _exit 3. 回收子进程状态 wait/waitpid 4. exec函数族 5. 守护进程 (1) 创建子进程,父进程退出 (2) 创建一个会话,并且以当前进程为会话组组长 (3) 与(1)步骤一样 (4) 更改进程的工作目录 chdir(”/”); (5) 设置权限掩码 umask(0);为了守护进程创建的文件对所有用户权限相同 (6) 关闭所有的打开文件 练习:文件拷贝的例子 源文件 ------------------------- 目标文件 创建2进程。。。。。。。。 进程A 拷贝前半部分 进程B 拷贝后半部分 首先:①打开2个文件 fd(只写) fs(只读) ②获取文件大小 num = lseek(fp,0,SEEK_END) ③fork ④父进程拷贝上半部分 (涉及到file 和 f_pos)----理解??? ⑤子进程拷贝下半部分 vim -d file.c file2.c 比较2文件大小 线程: 注意-----必须保证 主线程要比子线程后退出。。。。如主线程退出,不能确保子线程是否成功退出 线程:内核调度的最小单位 进程:程序执行和资源分配的最小单位 1. 每个线程都有一个tast_struct 2. 内核中,线程被称为轻量级进程。。。。。但在linux中称其为线程 3. 编程中可以使用多线程编程或者多进程编程 两者有什么区别呢:???? 多进程 ------------------------------------------------------------------ 多线程 ① 进程间通信A-B间数据交互 ------------------------- 多个线程tast_struct共享一个资源 所以,多线程效率高,但是数据的安全性要差(不能保持数据的一致性) 4.如何完成多线程编程???? ①多线程通过第三方的线程库(new POSIX Thread Library NPTL)来实现 ②线程共享的资源(与资源有关)------可执行指令,静态数据,进程中打开的文件描述符,信号处理函数 (与线程ID---TID)pc指针和相关计数器 今天的主要内容: 多线程的创建 编译线程 必须 指定的库 -lpthread 5.int pthread_create(pthread_t *thread, const pthread_attr_t *atrr, void * (*routine)(void *), void*arg) attr : 指定线程的属性 NULL表示使用缺省属性(线程默认属性) routine:线程的执行的函数 void * (*routine)(void *)返回值为void*,且参数为void*型的函数指针。。。。。 arg:传递给线程执行的函数的参数 NULL 返回值: 成功返回 0 失败返回 -1 获取线程号: gettid (LWP)标准库中没有这个函数 ----获得一个基于进程的ID号 .主线程退出,所有线程都退出 6. 回收子线程的状态。。。。 只需在主线程中调用。即可 int pthread_join(tid , void ** value ptr) ptr 是pthread_exit返回的状态。。。。。。 7.pthread_detach(tid) 主进程中调用,解除与主线程的关系,即子线程不需要主进程去调用pthread_join去回收子进程,。。。。。。。 8.线程的取消: 异步通知----信号的机制-----------直接将某一个线程关闭退出,不会有返回值。。。。。。 pthread_cancel(tid) 9,。线程间的同步和异步机制 怎么样才能同步? A (数据采集)------------------------------------B (数据处理) 必须A进程先采集,并将信息告知B进程,B进程在进行数据处理 即:同步机制, 让多个进程按照预订的先后顺序执行。。。。可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。 互斥机制:临界资源的互斥访问 A线程------write--临界资源 ---read -----B线程 由于时间片的问题,可能导致B线程read到不完全的数据 10.linux下提供的一机制 叫信号量。。。。。。信号量也叫信号灯-----先学习POSIX操作下的信号量。。。。。。。。。。信号量的值是非负整数 用来描述资源的个数,且一般工作在①管理资源的个数②二值信号量 0(无资源)和1(有资源) P操作--------------------------------------------------V操作 (银行家算法) 申请资源------------------------------------------释放资源 11.死锁:当某个进程持有一个资源,却无法释放这个资源 A-------------------------------------------B 获得资源--------------------------获得资源 sleep(1)<-----------------------提供A的唤醒条件 等待B的唤醒 无法释放---------------------无法释放 因此必须尽量避免死锁。。。。。 P(S): V(S): 12.pthread库常用的信号量操作函数:成功返回0,失败返回-1 ①int sem_init(sem_t *sem, int pshared, unsigned int value) sem 信号量,传&sem, pshared 一般为0 ,信号量初值。。。。。。 ② sem_wait(sem_t *sem) 阻塞操作 ③ sem_post(sem_t *sem) V操作 ④ sem_trywait ⑤ 获取信号量当前状态 例程:A ------------------------------------------------------B 初始化sem_init(&sem, 0)-------------------sem_wait() fgets() --------------------------------------------printf sem_post +1 13.互斥的使用: 互斥的是临界资源,而使用临界资源的代码叫临界区。。。。。。。。 使用互斥锁得目的保证数据的完整性。。。。 ① 互斥量 ② 互斥锁 gcc file.c -lpthread -02 加上-02 系统优化编译。。。。 必须用volatile 声明这个全局变量 进程间通信 1. 无名管道: ① 凡是具有亲缘关系的进程之间的通信 (继承了进程) ② 单工模式工作------只让父进程读,子进程写,避免了子进程读出自己写入的 2. pipe(int fd[2]) fd包含2个元素的整型数组 cd /proc/ID 查看管道是否创建成功 3. 管道读写注意: ① 读端读,写端写 ② 写数据,写入数据小于可写数据小于可写如数据则全部写入(PIPE_size 64kb) 写入数据大于可写数据则写入数据阻塞到可以完全写入 ③ 读数据: 要读数据小于可读数据,读所需数据 。。。。。。。大于。。。。。。。,全部读出返回到实际大小 ④ 对写端操作,读段必须存在