网站设计职业培训,旅游网站开发指导,建设英文外贸网站,广告推广图片线程 概念 线程是一个轻量级的进程#xff0c;为了提高系统的性能引入线程。 线程和进程都参与统一的调度。 在同一个进程中可以创建多个线程#xff0c;并且共享进程资源。 进程和线程区别(面试题) 相同点#xff1a;都为操作系统提供了并发执行的能力 不同点#xff1a; …线程概念线程是一个轻量级的进程为了提高系统的性能引入线程。线程和进程都参与统一的调度。在同一个进程中可以创建多个线程并且共享进程资源。进程和线程区别(面试题)相同点都为操作系统提供了并发执行的能力不同点资源和调度进程是系统资源分配的最小单位线程是资源调度的最小单位地址空间方面每个进程都有独立的地址空间同一个进程中的多个线程共享进程地址空间通信方面线程通信相对简单只需要通过全局变量就可以实现但是需要考虑临界资源访问的问题; 进程通信比较复杂需要借助进程间的通信机制(3-4g的内核空间)。安全性方面线程安全性差一些当进程结束时会导致所有线程退出; 进程相对安全。线程资源共享的资源可执行的指令、静态数据、进程中打开的文件描述符、信号处理函数、当前工作目录、用户ID、用户组ID私有的资源线程ID (TID)、PC(程序计数器)和相关寄存器、堆栈(局部变量, 返回地址)、错误号 (errno)、信号掩码和优先级、执行状态和属性函数接口创建线程pthread_create#includepthread.hintpthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*start_routine)(void*),void*arg);功能创建线程参数thread:线程标识attr线程属性NULL代表设置默认属性start_routine函数名代表线程函数(自己写)arg用来给前面函数传参返回值成功0失败错误码编译的时候需要加-lpthread 链接动态库退出线程pthread_exit#includepthread.hvoidpthread_exit(void*retval);功能用于退出线程的执行参数retval:线程退出时返回的值#include stdio.h#include pthread.h#include unistd.hvoid *handler(void *arg){printf(in the thread\n);pthread_exit(NULL); // 让线程退出while(1);return NULL;}int main(int argc, char const *argv[]){pthread_t tid;if(pthread_create(tid, NULL, handler, NULL) ! 0){perror(create thread err);}// 主线程printf(in the main\n);while(1);return 0;}回收线程资源#include pthread.hint pthread_join(pthread_t thread, void **retval);功能用于等待一个指定的线程结束阻塞函数参数thread创建的线程对象线程IDretval指针*value_ptr指向线程返回的参数一般为NULL返回值成功0失败errnoint pthread_detach(pthread_t thread);功能让线程结束时自动回收线程资源,让线程和主线程分离,非阻塞函数参数thread线程ID非阻塞式的例如主线程分离(detach)了线程T2那么主线程不会阻塞在pthread_detach()pthread_detach()会直接返回线程T2终止后会被操作系统自动回收资源#include stdio.h#include pthread.h#include unistd.hvoid *handler(void *arg){printf(in the thread\n);sleep(2);pthread_exit(NULL); // 让线程退出while(1);return NULL;}int main(int argc, char const *argv[]){pthread_t tid;if(pthread_create(tid, NULL, handler, NULL) ! 0){perror(create thread err);}// pthread_join(tid, NULL); // 阻塞等待指定线程退出回收资源pthread_detach(tid); // 非阻塞,让指定的线程为分离态,结束时自动回收资源// 主线程printf(in the main\n);while(1);return 0;}练习输入输出quit结束通过线程实现数据的交互主线程循环从终端输入线程函数将数据循环输出当输入quit结束程序。全局变量加上标志位(flag)实现主线程输入一次修改标志位从线程打印一次也修改标志位 int flag0;#include stdio.h#include pthread.h#include unistd.h#include string.hchar buf[32] {};int flag 0;void *handler(void *arg){while (1){if (flag 1){if (!strcmp(buf, quit))break;printf(%s\n, buf);flag 0;}}return NULL;}int main(int argc, char const *argv[]){pthread_t tid;if (pthread_create(tid, NULL, handler, NULL) ! 0){perror(create thread err);}while (1){scanf(%s, buf);flag 1;if (!strcmp(buf, quit))break;}pthread_join(tid, NULL);return 0;}在应用层中有这两个概念同步现在有两件事都是你应该去做的事情那么这两件事是不是有先后的顺序异步我在做一件事情的同时还可以去做另一件事情线程同步概念多个线程(任务)按照约定的顺序相互配合完成一件事情同步机制通过信号量实现线程同步信号量通过信号量实现同步操作 由信号量来决定线程继续运行还是阻塞等待。信号量代表一类资源其值可以表示系统中该资源的数量。信号量的值0 表示有资源可以用可以申请到资源。信号量的值0: 表示没有资源可以用无法申请到资源阻塞。信号量还是受保护的变量只能通过三种操作来访问初始化P操作(申请资源)V操作释放资源sem_init信号量初始化sem_wait申请资源P操作如果没有资源可用则阻塞否则就申请到资源 -1sem_post释放资源V操作非阻塞1int sem_init(sem_t *sem, int pshared, unsigned int value)功能初始化信号量参数sem初始化的信号量对象pshared信号量共享的范围(0: 线程间使用 非0:1进程间使用)value信号量初值返回值成功 0失败 -1int sem_wait(sem_t *sem)功能申请资源 P操作参数sem信号量对象返回值成功 0失败 -1注此函数执行过程当信号量的值大于0时表示有资源可以用则继续执行同时对信号量减1当信号量的值等于0时表示没有资源可以使用函数阻塞int sem_post(sem_t *sem)功能释放资源 V操作参数sem信号量对象返回值成功 0失败 -1注释放一次信号量的值加1函数不阻塞#include stdio.h#include semaphore.hint main(int argc, char const *argv[]){sem_t sem;if(sem_init(sem, 0, 1) 0){perror(sem init err);return -1;}// 申请资源 - P操作sem_wait(sem);printf(hello\n);// 释放资源sem_post(sem);sem_wait(sem); // 没有释放资源,会进入阻塞状态printf(world\n);return 0;}线程互斥互斥概念多个线程访问临界资源时同一时间只能一个线程访问临界资源多个线程共同访问的数据且一次仅允许一个线程所使用的资源通过互斥锁可以实现互斥机制主要用来保护临界资源每个临界资源都由一个互斥锁来保护线程必须先获得互斥锁才能访问临界资源访问完资源后释放该锁。如果无法获得锁线程会阻塞直到获得锁为止。互斥锁的操作方式初始化申请锁(上锁) 阻塞当申请不到锁时(表示锁被其它线程占用)是阻塞的释放锁(解锁) 非阻塞注意上锁和解锁需要成对存在函数接口int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr)功能初始化互斥锁参数mutex互斥锁attr: 互斥锁属性 // NULL表示缺省属性返回值成功 0失败 -1int pthread_mutex_lock(pthread_mutex_t *mutex)功能申请互斥锁参数mutex互斥锁返回值成功 0失败 -1注和pthread_mutex_trylock区别pthread_mutex_lock是阻塞的pthread_mutex_trylock不阻塞如果申请不到锁会立刻返回int pthread_mutex_unlock(pthread_mutex_t *mutex)功能释放互斥锁参数mutex互斥锁返回值成功 0失败 -1int pthread_mutex_destroy(pthread_mutex_t *mutex)功能销毁互斥锁参数mutex互斥锁补充死锁是指两个或两个以上的进程或线程在执行过程中由于竞争资源或者由于彼此通信而造成的一种阻塞的现象若无外力作用它们都将无法推进下去。死锁产生的四个必要条件1、互斥使用即当资源被一个线程使用(占有)时别的线程不能使用2、不可抢占资源请求者不能强制从资源占有者手中夺取资源资源只能由资源占有者主动释放。3、请求和保持即当资源请求者在请求其他的资源的同时保持对原有资源的占有。循环等待即存在一个等待队列P1占有P2的资源P2占有P3的资源P3占有P1的资源。这样就形成了一个等待环路。注意当上述四个条件都成立的时候便形成死锁。当然死锁的情况下如果打破上述任何一个条件便可让死锁消失。