进程: 是一个PCB,在内存中运行的程序的描述,是 系统资源分配的基本单位。Linux下进程是一个task_struct结构体,这个结构体存储在内核中。
线程: 进程中的一条执行流,是 CPU运行调度的基本单位。共享PCB的数据段,代码段,文件描述符表等信息,独有线程id,栈,上下文数据。
进程控制
进程创建
pid_t fork():
复制父进程PCB中的数据创建子进程,代码共享栈独有。
父子进程谁先运行不一定。
采用写时拷贝。
写时拷贝:子进程创建后,父子进程虚拟地址空间不同但指向同一块物理空间,当某进程对空间内数据进行操作时,给子进程重新开辟空间,进行数据拷贝。
pid_t vfork():
创建子进程后阻塞父进程,子进程运行结束或程序替换父进程运行。
父子进程共用同一块虚拟内存,共用同一个栈,因此子进程在main函数中使用return退出会释放所有资源,导致父进程运行出错。
进程终止
return:非main函数中只能退出函数,不能退出进程;
exit():库函数,在程序任意位置退出一个进程,退出时刷新缓冲区;
_exit():系统调用函数,在程序任意位置退出一个进程;
进程等待
父进程等待子进程退出,获取退出子进程返回值,释放子进程所有资源。如果子进程退出父进程却没有等待子进程退出(父进程不知道子进程退出了),子进程成为僵尸进程。
int wait(int* status):处理任意退出的子进程;
参数:用于获取退出子进程的返回值;
阻塞接口,不处理则等待;
int waitpid(int pid, int* status, int option):处理指定退出的子进程;
参数:指定子进程id(-1表示任意子进程),获取退出子进程的返回值,设置阻塞(0阻塞,WNOHANG非阻塞);
线程控制
操作线程的接口都是库函数,头文件pthread.h,编译和链接要链接库pthread。
线程创建
int pthread_create(pthread_t *tid, pthread_attr_t* attr, void*(start_routine)(void*), void* arg);
tid:用于获取创建的线程id;
attr:线程属性,通常置NULL;
start_routine:线程的入口函数;
arg:通过线程入口函数给线程传递的参数;
返回值:成功0,失败非0;
线程终止
主线程退出不会导致进程退出,所有线程退出进程才会退出。
return:在线程入口函数调用,退出线程;
pthread_exit():任意位置调用退出线程;
pthread_cancel(pthread_t tid):退出指定线程,返回值是一个宏PTHREAD_CANCELED(-1);
线程等待
默认情况下,线程退出资源不会被回收,需要其他线程等待,获取退出线程的返回值,释放资源;
int pthread_join(pthread_t tid, void** retval);
retval:退出线程的返回值;
返回值:成功0,失败返回错误编号;
线程不是必须被等待,线程属性有一个分离属性,默认是joinable,处于该状态的线程退出后不会释放资源,需要被等待
线程分离
设置线程的分离属性为detach,处于detach状态的线程退出后自动释放资源,不需要被等待==(只有不关心线程返回值,也不想等待线程退出时才会分离线程)==。
void pthread_detach(pthread_t tid);
pthread_self();//线程获取自身id
pthread_detach(pthread_self());//线程自己分离自己