小知识:
修改文件夹下所有文件的权限
sudo chmod -R 777 filename
filename为要修改的文件夹名字。-R应该是表示递归修改filename文件夹下所有文件的权限。
其实整个命令的形式是
sudo chmod -(代表类型)×××(所有者)×××(组用户)×××(其他用户)
线程
• 线程有时被称为轻量级进程(LightweightProcess,LWP),是程序执行流的最小单元。
• 线程是进程中的一个实体,是被系统独立调度和分派的基本单位,
• 线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。
引入线程前, 进程是资源分配的基本单位,也是调度的基本单位引入线程后, 进程是资源分配的基本单位, 线程是调度的基本单位
线程
• 允许程序执行不止一个任务的机制• 并行执行• 受操作系统异步调度, 是操作系统调度的最小单元,• 进程内的不同线程执行是同一程序的不同部分
主线程
• 线程可由进程创建,操作系统在创建进程时会创建一个主线程,程序main()函数是主线程的入口。
- 由于进程的地址空间是私有的,因此在进程间上下文切换时,系统开销比较大, 在同一个进程中创建的线程共享该进程的地址空间,
- 每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
- 线程也有就绪、阻塞和运行三种基本状态。
- Linux里同样用task_struct来描述一个线程。 线程和进程都参与统一的调度
- 多线程通过第三方的线程库来实现 New POSIX ThreadLibrary (NPTL)
多线程优点
经济实惠
• 分配的资源少、线程切换比进程切换快、维护线程的开销小
资源共享
• 线程共享它们所属进程的存储器和资源。
提高了响应速度
• 允许程序在它的一部分被阻塞或正在执行一个冗长 的操作时持续运行
提高了多处理机体系结构的利用率
• 在多CPU机器中,多线程提高了并发性
线程共享的资源
一个进程中的多个线程共享以下资源
• 可执行的指令
• 静态数据
• 进程中打开的文件描述符
• 信号处理函数
• 当前工作目录
• 用户ID
• 用户组ID
线程私有的资源
每个线程私有的资源如下
• 线程ID (TID)
• PC(程序计数器)和相关寄存器
• 堆栈
局部变量
返回地址
• 错误号(errno)
• 信号掩码和优先级
• 执行状态和属性
线程创建
NPTL线程库中提供了如下基本操作
• 创建线程
• 删除线程
• 控制线程
线程间同步和互斥机制
• 信号量
• 互斥锁
• 条件变量
pthread_create
#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_tattr, void * ( routine)(void *), void *arg);
函数参数
thread:创建的线程
attr:指定线程的属性,NULL表示使用缺省属性
routine:线程执行的函数
arg: 传递给线程执行的函数的参数
函数返回值
成功:0
出错:-1
PTHREAD_CREATE_DETACHED分离线程没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源
PTHREAD _CREATE_JOINABLE线程的默认属性是非分离状态,这种情况下,原有的线程等待创建的线程结束。只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源
pthread_join
#include <pthread.h> int pthread_join(pthread_t thread, void **value_ptr)
线程执行完后如果不join的话,线程的资源会一直得不到释放而导致内存泄漏!
函数参数
thread:要等待的线程
value_ptr:指针*value_ptr指向线程返回的参数
函数返回值
成功:0
出错:-1
pthread_cancel
#include <pthread.h> int pthread_cancel(pthread_t thread)
函数参数
thread:要取消的线程
函数返回值
成功:0
出错:-1
pthread_exit
#include <pthread.h> int pthread_exit(void *value_ptr)
函数参数
value_ptr:线程退出时返回的值
函数返回值
成功:0
出错:-1
在不终止整个进程的情况下,单个线程可以有三种方式停止其工作流并退出
1.线程从其工作函数中返回, 返回值是线程的退出码
2.线程可以被同一进程中的其他线程取消
3.线程自己调用pthread_exit
实例
#include <pthread.h> #include <semaphore.h> #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> void *thread1_func(void *arg) { int n; for (n = 0; n < 30; n++) { sleep(1); printf("AAAAAAAAAA\n"); } pthread_exit(NULL); //return NULL; } void *thread2_func(void *arg) { int n; for (n = 0; n < 30; n++) { sleep(1); printf("BBBBBBBBBB\n"); } return NULL; } int main(int argc, char *argv[]) { pthread_t tid1, tid2; if (pthread_create(&tid1, NULL, thread1_func, NULL) != 0) { perror("main: pthread_create thread_1 failed"); return 1; } else { printf("main: pthread_create thread_1 succeed!\n"); } if (pthread_create(&tid2, NULL, thread2_func, NULL) != 0) { perror("main: pthread_create thread_2 failed"); return 1; } else { printf("main: pthread_create thread_2 succeed!\n"); } if (pthread_join(tid1, NULL) != 0) { perror("main: pthread_join thread_1 failed"); } if (pthread_join(tid2, NULL) != 0) { perror("main: pthread_join thread_2 failed"); } printf("main is exiting.\n"); return 0; }
编译
gcc thread.c -o run -lpthread
进程调度有一定随机性
whereis pthread
线程查看
ps –efL
共用同一个pid,全局变量共享,打开的文件共享。
如果LWP与PID值相同则为主线程
•UID:用户ID
• PID:process id 进程id
• PPID: parent process id 父进程id
• LWP:表示这是个线程;要么是主线程(进程),要么是线程
• NLWP: num of light weight process 轻量级进程数量,即线程数量
• STIME: start time 启动时间TIME: 占用的CPU总时间
• TTY:该进程是在哪个终端运行的
• CMD:进程的启动命令
ps -ef f
• 用树形显示进程和线程