Linux系统编程——线程

51 篇文章 6 订阅

一、线程概念

  1. 基础

    线程又称LWP:light weight process 轻量级的进程,(在linux环境下)本质仍是进程。
    
    进程:独立地址空间,拥有PCB
    线程:有独立的PCB,但没有独立的地址空间(共享)
    
    区别:
    	在于是否共享地址空间。 	独居(进程);合租(线程)
    
    Linux下:
    	线程:最小的执行单位
    	进程:最小分配资源单位,可看成是只有一个线程的进程
    
    	GDB和信号诞生时间比线程早,故配合使用会很麻烦。
    
    线程越多的程序理论上越可能争夺到cpu资源,但不是一味的扩展线程数,会有峰值。
    
    ps -Lf 进程id //查看线程运行情况 包括线程号(cpu执行的最小单位,不等同于线程id)  
    
  2. linux内核线程实现原理(了解即可)

    1.轻量级进程(lwp),也有PCB,创建线程使用的底层函数和进程一样,都是clone。
    2.从内核里看进程和线程是一样的,都有各自不同的PCB,但是PCB中指向内存大额三级页表是相同的(详见下面三级映射)。
    3.进程可以锐变成线程
    4.线程可看做寄存器和栈的集合
    5.linux下,线程是最小执行单位,进程是最小分配资源单位
    
    三级映射:
    	进程PCB->页目录(可看成数组,首地址位与PCB中)->页表->物理页面->内存单元。
    	
    	PCB中由三级映射出物理地址。 
    		PCB中描述虚拟地址的指针指向一个【页面】(页面中都是指针),
    		这个页面中的指针再指向一个【页表】(页表中也都是指针),
    		页表再对应一个【页目录】(页目录中都是内存单元(对应物理内存))。
    	
    多进程:
    	每个进程对应不同的PCB,且有不同的页面指针。故不共享数据。
    
    多线程:
    	每个线程对应不同的PCB,但有相同的页面指针。故共享数据。
    

    在这里插入图片描述

  3. 线程共享资源

    1.文件描述符表
    2.每种信号的处理方式 (线程和信号尽可能不混用)
    3.当前工作目录
    4.用户ID 和 组ID
    5.内存地址空间(.text/.data/.bss/heap/共享库,栈不共享)
    
  4. 线程非共享资源

    1.线程ID
    2.处理器现场(寄存器相关)和栈指针(内核栈)
    3.独立的栈空间(用户空间栈)
    4.errno 变量
    5.信号屏蔽字
    6.调度优先级
    
  5. 线程优、缺点在这里插入图片描述

二、线程控制原语(相关函数)

线程相关函数出错都返回errno,
故利用char * strerror(errno)函数来打印出错误信息。
而不用perror()。
  1. pthread_self

    	man 3 pthread_self
    	
    		1)NAME
    	       		pthread_self - obtain ID of the calling thread
    	
    		2)SYNOPSIS
    		       #include <pthread.h>
    		
    		       pthread_t pthread_self(void);
    		
    		       Compile and link with -pthread.  //特别注意
    		
    		3)RETURN VALUE
    		       This function always succeeds, returning the calling thread's ID.
    
    
  2. pthread_create

    man 3 pthread_create
    		
    			1)NAME
    		       	pthread_create - create a new thread
    		
    			2)SYNOPSIS
    			       #include <pthread.h>
    			
    			       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
    			                          void *(*start_routine) (void *), void *arg);
    			
    			       Compile and link with -pthread. //特别注意
    	
    			3)PARAMETER
    				 (1)thread:值结果参数,线程ID。
    				 (2)attr:设置线程属性。NULL表示使用默认属性(共两种属性)PTHREAD_CREATE_JOINABLE,可配合pthread_join()使用;
    				 		  另一种属性为PTHREAD_CREATE_DETACHED,不能配合pthread_join()使用,会报错。详见下 7.
    				 (3)start_routine:子线程回调函数。若线程创建成功,该函数自动被调用。
    				 (4)arg:start_routine指定函数的参数。没有的话传NULL。
    				 		传参时一定要注意,不要传地址(数据共享原因),要传值进去,否则当回调函数得到数据时会出错。
    				 		
    			4)RETURN VALUE
    	       			On success, pthread_create() returns 0; on error, it returns an error number, and the contents of *thread are undefined.
    	
    	DEMO:
    			https://github.com/Panor520/LinuxCode/tree/master/thread/pthread.c
    	
    	循环创建多个线程DEMO:
    			https://github.com/Panor520/LinuxCode/tree/master/thread/pthread_muti.c
    	
    
  3. pthread_exit

    exit(0); //退出当前进程
    return 0;//返回到调用者那里去。
    		//main函数中的return就代表进程结束。
    pthread_exit(0); //退出当前线程
    
    man 3 pthread_exit
    
    	1.NAME
      	 pthread_exit - terminate calling thread
    
    	2.SYNOPSIS
           #include <pthread.h>
    
           void pthread_exit(void *retval);
    
           Compile and link with -pthread.
    	
    	3.PARAMETER
    		retval:返回值。类似于exit(0);中的0.
    			
    	4.RETURN VALUE
       This function does not return to the caller.
    	
    	DEMO:
    			https://github.com/Panor520/LinuxCode/tree/master/thread/pthread_muti.c
    
  4. pthread_join

    man 3 pthread_join
    	
    1.NAME
       		pthread_join - join with a terminated thread
    
    2.SYNOPSIS
       		#include <pthread.h>
    
       		int pthread_join(pthread_t thread, void **retval);
    
      		Compile and link with -pthread.
    3.PARAMETER
    		thread:线程ID
    		retval:值结果参数,得到pthread_create指定的线程回调函数的结果。
    				为什么是(viod**)的返回类型。因为回调函数是void *,而再回调void* 就是void**.
    				类似的wait回收int型数据为 int ——> int *
    					则有			  void* ——> void **
    			注意:
    				当线程被pthread_cancel()后,retval的值是-1,代表线程非正常消亡
    				
    4.RETURN VALUE
       			On success, pthread_join() returns 0; on error, it returns an error number.
    	
    DEMO:
    			https://github.com/Panor520/LinuxCode/tree/master/thread/pthread_join.c
    
  5. pthread_cancel

    man 3 pthread_cancel
    
    1.NAME
       		pthread_cancel - send a cancellation request to a thread
    	
    2.SYNOPSIS
       		#include <pthread.h>
    
       		int pthread_cancel(pthread_t thread);
    
       		Compile and link with -pthread.
    
    3.PARAMETER
    		thread:指定要取消的进程ID
    
    4.RETURN VALUE
       		On success, pthread_cancel() returns 0; on error, it returns a nonzero error number.
    
    5.注意
    		只有程序运行到取消点后(取消点函数执行完毕)才会取消,如果线程运行中(指回调函数)没有取消点,那就一直执行,不会取消。
    		当程序中没有取消点时,可自行增加取消点,利用函数pthread_testcancel()//man pthread_testcancel
    		取消点( man pthreads 中可查看):
    				一些和内核进行交互的函数,如sleep()close()等等常用的函数.
    		
    DEMO:
    	https://github.com/Panor520/LinuxCode/tree/master/thread/pthread_cancel.c
    
  6. pthread_detach

    
    man 3 pthread_detach
    创建完线程后再指定线程分离,线程执行完自行回收,不能和pthread_join同时使用。
    
    	1.NAME
    	      	pthread_detach - detach a thread
    
    	2.SYNOPSIS
       			#include <pthread.h>
    
      			int pthread_detach(pthread_t thread);
    
       			Compile and link with -pthread.
       	3.RETURN VALUE
       On success, pthread_detach() returns 0; on error, it returns an error number.
    	
    Demo:
    		https://github.com/Panor520/LinuxCode/tree/master/thread/pthread_detach.c
    
  7. pthread_create 参数2设置线程属性

    简单步骤:
    		pthread_attr_t attr;//创建线程属性结构体
    		pthread_attr_init(&attr);//初始化结构体
    		pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);//设置线程属性结构体为 detach 状态
    		pthread_create(&tid,&attr,tfunc,NULL);//利用线程属性结构体创建线程
    		pthread_attr_destroy(&attr);//在利用完线程属性结构体后销毁该结构体
    
    
    函数详解:
    
    (1pthread_attr_init()pthread_attr_destroy()
    		
    		man 3 pthread_attr_init
    
    		1.NAME
    	    	   pthread_attr_init, pthread_attr_destroy - initialize and destroy thread attributes object
    	
    		2.SYNOPSIS
    	 	      #include <pthread.h>
    	
    	 	      int pthread_attr_init(pthread_attr_t *attr);   //类似malloc()
    	   	 	  int pthread_attr_destroy(pthread_attr_t *attr); //类似free()
    	
    	  	      Compile and link with -pthread.
    	
    	
    	
    		3.RETURN VALUE
    		       On success, these functions return 0; on error, they return a nonzero error number.
    
    
    (2)pthread_attr_setdetachstate()pthread_attr_getdetachstate()
    		1.NAME
           			pthread_attr_setdetachstate, pthread_attr_getdetachstate - set/get detach state attribute in thread attributes object
    
    		2.SYNOPSIS
           			#include <pthread.h>
    
           			int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
           			int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
    				Compile and link with -pthread.
    				
    		3.PARAMETER
    				1)attr
    				2)detachstate:
    				       PTHREAD_CREATE_DETACHED
    				              Threads that are created using attr will be created in a detached state.
    				
    				       PTHREAD_CREATE_JOINABLE
    				              Threads that are created using attr will be created in a joinable state.
    						
    				 attention:
          				    	The default setting of the detach state attribute in a newly initialized thread attributes object is PTHREAD_CREATE_JOIN‐
           ABLE.
    		
    		4.RETURN VALUE
           			On success, these functions return 0; on error, they return a nonzero error number.
    
    DEMO:
    		https://github.com/Panor520/LinuxCode/tree/master/thread/pthread_attr_init.c
    
  8. 线程使用相关注意事项

    1.主线程退出其他线程不退出,主线程应调用pthread_exit。
    2.避免僵尸进程有两种方法:
    			1)pthread_join //线程创建默认属性
    			2)pthread_detach //需指定设置,两种设置方法
    						1.pthread_create()时利用线程属性指定
    						2.pthread_create()后指定。
    3.malloc和mmap申请的内存可以被其他线程释放。
    4.应避免在多线程中调用fork(),子进程中只有调用fork的线程存在,其他线程在子进程均pthread_exit().
    5.应避免在多线程中引入信号机制。
    		理由:每个线程有独立的PCB,故mask(屏蔽字集合)不同,但每个线程对信号的处理是共享的(因为在一个进程下),
    			  而由哪个线程来获取信号是靠CPU分配的,而当一个线程处理完之后,其他线程是不受影响的。
    

三、线程和进程控制原语比较

在这里插入图片描述

四、线程同步概念

	官方释义:
			线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不放回。同时其它线程为保证数据一致性,不能调用该功能。
	
	我的理解:
			就是保证不同线程方法调用共享数据时,要保证上一个线程执行完毕后,下一个线程再执行。保证共享数据一致性。


	同步的目的:
			避免数据混乱。解决与时间有关的错误。
			实际上不仅线程间需要同步,进程间、信号间等等都需要同步机制。

	数据混乱原因:
			1.资源共享
			2.调度随机
			3.线程间缺乏必要的同步机制。#下面主要就把讲这个。
			

五、线程同步——互斥锁(互斥量)

  1. 概念

    Linux中提供一把互斥锁mutex(也称为互斥量)。
    
    每个线程在对资源操作前都尝试加锁(没拿到锁就一直阻塞等待锁可用),成功加锁才能操作,操作结束后解锁。
    
    资源还是共享的,线程间也还是竞争的。
    
    但通过“锁”将资源访问变成互斥操作,但注意同一时间只能有一个线程持有该锁。
    
    建议锁,没有强制性。
    		所有线程在访问公共数据前先拿锁再访问。但锁本身不具备强制性。
    
    

    在这里插入图片描述

  2. 互斥锁实现

    使用互斥锁时尽可能访问共享数据前加锁,访问后立即解锁。
    
    互斥锁本质是结构体。可以看成整数。初值(pthread_mutex_init()后)为1.
    加锁: -- 阻塞线程。
    解锁: ++ 唤醒阻塞线程。
    
    实现步骤:
    	 pthread_mutex_t mylock;//定义互斥锁结构体,应声明为全局变量,放在全局位置
    	 pthread_mutex_init(&mylock,NULL);//初始化互斥锁,第二个参数默认NULL即可
    	 
    	 pthread_mutex_lock(&mylock);//加锁,线程阻塞,等待锁释放
    	 pthread_mutex_trylock(&mylock)//加锁,线程不阻塞,立即返回,线程不会阻塞
    	 
    	 pthread_mutex_unlock(&mylock);//解锁
    	 pthread_mutex_destroy(&mylock);//销毁锁
    
    
    1.pthread_mutex_t
    		mutex锁结构体
    
    
    2.pthread_mutex_init()、pthread_mutex_destroy()
    	
    		man pthread_mutex_init
    		
    		(1)NAME
         		 	 pthread_mutex_destroy, pthread_mutex_init — destroy and initialize a mutex
    		(2)SYNOPSIS
         		 	 #include <pthread.h>
    
           			int pthread_mutex_destroy(pthread_mutex_t *mutex);
          			int pthread_mutex_init(pthread_mutex_t *restrict mutex,
             		const pthread_mutexattr_t *restrict attr);
           			pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;3)PARAMETER
    				1.mutex:互斥锁结构体
    						restrict关键字:只能引用定义的指针,不能使用另外赋值的指针。
    						例:int *p=0xdddd;
    							int * q=p;
    							当定义函数int test(int * restrict x);时,参数x知道能传p,不能穿q。
    				2.attr
    						填NULL即可。
    				
    		(4)RETURN VALUE
           			If successful, the pthread_mutex_destroy() and pthread_mutex_init() functions shall return zero; otherwise, an error num‐
           			ber shall be returned to indicate the error.
    
    
    3.pthread_mutex_lock()pthread_mutex_unlock()
    		
    		man pthread_mutex_lock
    	
    		(1)NAME
           			pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock — lock and unlock a mutex
    
    		(2)SYNOPSIS
    		       #include <pthread.h>
    		
    		       int pthread_mutex_lock(pthread_mutex_t *mutex);
    		       int pthread_mutex_trylock(pthread_mutex_t *mutex);
    		       int pthread_mutex_unlock(pthread_mutex_t *mutex);
    		(3)RETURN VALUE
          			 If successful, the pthread_mutex_lock(), pthread_mutex_trylock(), and pthread_mutex_unlock() functions shall return zero;
         			  otherwise, an error number shall be returned to indicate the error.
    
    DEMO:
    		https://github.com/Panor520/LinuxCode/tree/master/thread/pthread_mutex.c
    

六、死锁

两种情况:
		1.线程试图对同一个互斥量A加锁两次
		2.线程1 拥有 A锁,请求获取 B锁;线程2 拥有 B锁,请求获得A锁。
	
DEMO:

在这里插入图片描述

七、读写锁

  1. 概念

    锁只有一把:
    		以读方式给数据加锁——读锁。
    
    		以写方式给数据加锁——写锁。
    
    读共享,写独占。
    写锁优先级高。
    
    【相较于互斥量而言,当读线程多的时候,提高访问效率】。
    
    特性如下图:
    

    在这里插入图片描述

  2. 读写锁实现

    实现步骤:
    		pthread_rwlock_t mylock;//定义读写锁全局变量
    		pthread_rwlock_init(&mylock,NULL);//动态初始化读写锁
    		
    		pthread_rwlock_t mylock = PTHREAD_MUTEX_INITIALIZER
    		
    		pthread_rwlock_rdlock(&mylock);//加读锁,阻塞线程直到锁可用
    		pthread_rwlock_tryrdlock(&mylock);//加读锁,不阻塞线程,直接返回结果
    		
    		pthread_rwlock_wrlock(&mylock);//加写锁,阻塞线线程直到锁可用
    		pthread_rwlock_trywrlock(&mylock);//加写锁,不阻塞线程,直接返回结果
    		
    		pthread_rwlock_unlock(&mylock);//解锁
    		
    		pthread_rwlock_destroy(&mylock);//销毁读写锁
    
    
    函数解析:
    1.pthread_rwlock_init()pthread_rwlock_destroy()
    		man  pthread_rwlock_init
    
    		(1)NAME
           				pthread_rwlock_destroy, pthread_rwlock_init — destroy and initialize a read-write lock object
    
    		(2)SYNOPSIS
    			       #include <pthread.h>
    			
    			       int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
    			       int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
    			           const pthread_rwlockattr_t *restrict attr);
    			       pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
    
    		(3)PARAMETER
    					1.rwlock:互斥锁结构体
    							restrict关键字:只能引用定义的指针,不能使用另外赋值的指针。
    							例:int *p=0xdddd;
    								int * q=p;
    								当定义函数int test(int * restrict x);时,参数x知道能传p,不能穿q。
    					2.attr
    							填NULL即可。
    						
    		(4)RETURN VALUE
          				If successful, the pthread_rwlock_destroy() and pthread_rwlock_init() functions shall return zero;  otherwise,  an  error
           				number shall be returned to indicate the error.
    	
    		
    2.pthread_rwlock_rdlock(), pthread_rwlock_tryrdlock()
    		man  pthread_rwlock_rdlock
    		
    		(1)NAME
    		       pthread_rwlock_rdlock, pthread_rwlock_tryrdlock — lock a read-write lock object for reading
    		
    		(2)SYNOPSIS
    		       #include <pthread.h>
    		
    		       int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
    		       int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);	
    
    		(3)RETURN VALUE
    			成功:0
    			失败:错误号。errno。
    
    
    3.pthread_rwlock_wrlock(),pthread_rwlock_trywrlock()
    
    		(1)NAME
           			pthread_rwlock_trywrlock, pthread_rwlock_wrlock — lock a read-write lock object for writing
    
    		(2)SYNOPSIS
    		       #include <pthread.h>
    		
    		       int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
    		       int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
    		
    		(3)RETURN VALUE
    			成功:0
    			失败:错误号。errno。
    
    
    4.pthread_rwlock_unlock()
    
    		(1)NAME
    		       pthread_rwlock_unlock — unlock a read-write lock object
    		
    		(2)SYNOPSIS
    		       #include <pthread.h>
    		
    		       int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
    		
    		(3)RETURN VALUE
    		       If  successful,  the  pthread_rwlock_unlock() function shall return zero; otherwise, an error number shall be returned to
    		       indicate the error.
    		
    
    DEMO:
    		https://github.com/Panor520/LinuxCode/tree/master/thread/pthread_rwlock.c 
    

八、条件变量

  1. 条件变量概念

    条件变量本身不是锁,但可以造成线程阻塞。
    通常与互斥锁配合使用(例如下面的生产者消费者模型)。
    
    主要函数如下:
    

    在这里插入图片描述

    man 手册找不到下列函数。就用下面的安装命令安装。
    sudo apt-get install manpages-posix-dev
    
    1. pthread_cond_t
     
    		pthread_cond_t cond;//条件变量结构体
    初始化条件变量:
    		pthread_cond_init(&cond,NULL);						//动态初始化
    		pthread_cond_t cond = PTHREAD_COND_INITIALIZER;		//静态初始化
    
    
    
    2. pthread_cond_init()pthread_cond_destroy()
    
    		1)NAME
    		       pthread_cond_destroy, pthread_cond_init — destroy and initialize condition variables
    		
    		2)SYNOPSIS
    		       #include <pthread.h>
    		
    		       int pthread_cond_destroy(pthread_cond_t *cond);
    		       int pthread_cond_init(pthread_cond_t *restrict cond,
    		           const pthread_condattr_t *restrict attr);
    		       pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    		       
    		3)PARAMETER
    				cond :条件变量结构体
    				attr :NULL即可。
    				
    		4)RETURN VALUE
    		       If successful, the pthread_cond_destroy() and pthread_cond_init() functions shall return zero; otherwise, an error number
    		       shall be returned to indicate the error.
    
    
    
    3.pthread_cond_timedwait(), pthread_cond_wait()
    
    		1)NAME
    		       pthread_cond_timedwait, pthread_cond_wait — wait on a condition
    		
    		2)SYNOPSIS
    		       #include <pthread.h>
    		
    		       int pthread_cond_timedwait(pthread_cond_t *restrict cond,
    		           pthread_mutex_t *restrict mutex,
    		           const struct timespec *restrict abstime);
    		       int pthread_cond_wait(pthread_cond_t *restrict cond,
    		           pthread_mutex_t *restrict mutex);
    
    		3)PARAMETER
    				cond  :互斥量结构体
    				mutex :初始化过的互斥锁结构体
    				
    		4)RETURN VALUE
    				 Upon  successful  completion, a value of zero shall be returned; otherwise, an error number shall be returned to indicate
           				the error.
    
    4. pthread_cond_broadcast(),//唤醒阻塞在条件变量上的 所有线程
       pthread_cond_signal()	//唤醒阻塞在条件变量上的 (至少)一个线程
    
    		1)NAME
    		       pthread_cond_broadcast, pthread_cond_signal — broadcast or signal a condition
    		
    		2)SYNOPSIS
    		       #include <pthread.h>
    		
    		       int pthread_cond_broadcast(pthread_cond_t *cond);
    		       int pthread_cond_signal(pthread_cond_t *cond);
    
    		3)PARAMETER
    				cond:条件变量结构体
    		
    		4)RETURN VALUE
    		       If successful, the pthread_cond_broadcast() and pthread_cond_signal() functions shall return zero;  otherwise,  an  error
    		       number shall be returned to indicate the error.
    
    DEMO:
    		详见 八、生产者与消费者
    
  2. wait和timewait详解
    在这里插入图片描述

九、生产者消费者模型(条件变量实现)

  1. 基础
    在这里插入图片描述

  2. DEMO

    源码连接

十、信号量

  1. 基础

    信号量和互斥锁(1)类似,只是互斥锁最多只允许一个线程访问共享数据,而信号量(N)可以是多个线程访问。
    
    
    sem_t sem;//定义类型
    sem_wait(); //一次调用,做一次-- 操作,当信号量的值为 0 时,再次 -- 会阻塞。(对比 pthread_mutex_lock)
    sem_post();//一次调用,做一次++ 操作,当信号量的值为 N 时,再次 ++ 就会阻塞。(对比pthread_mutex_unlock)
    
  2. 涉及函数

    1.sem_t sem;//定义类型
    
    2.sem_init()
    		man sem_init
    		1)NAME
    		       sem_init - initialize an unnamed semaphore
    		
    		2)SYNOPSIS
    		       #include <semaphore.h>
    		
    		       int sem_init(sem_t *sem, int pshared, unsigned int value);
    		
    		       Link with -pthread.
    		3)PARAMETER
    				sem:信号量
    				pshared :0 线程同步
    						  1 进程同步
    				value :N值。信号量值。 (指定同时访问的线程数)
    		4)RETURN VALUE
           			sem_init() returns 0 on success; on error, -1 is returned, and errno is set to indicate the error.
    
    
    3.sem_destroy()
    
    		1)NAME
    		       sem_destroy - destroy an unnamed semaphore
    		
    		2)SYNOPSIS
    		       #include <semaphore.h>
    		
    		       int sem_destroy(sem_t *sem);
    		
    		       Link with -pthread.
    		3)RETURN VALUE
    		       sem_destroy() returns 0 on success; on error, -1 is returned, and errno is set to indicate the error.
    
    
    4.sem_wait(),sem_timedwait() //(对比 pthread_mutex_lock)
    		man sem_wait
    		1)NAME
    		       sem_wait, sem_timedwait, sem_trywait - lock a semaphore
    		
    		2)SYNOPSIS
    		       #include <semaphore.h>
    		
    		       int sem_wait(sem_t *sem);
    		
    		       int sem_trywait(sem_t *sem);
    		
    		       int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
    		
    		       Link with -pthread.
    		3)PARAMETER
    				abs_timeout :采用的是绝对时间。和普通的定时不同。
    							例:定时1秒
    								time_t cur = time(NULL);//获取当前时间
    								struct timespect t;//定义时间结构体变量
    								t.tv_sec = cur+1;//定时1s.
    								t.tv_nsec = t.tv_sec +100;
    								sem_timewait(&sem,&t);//应用传参
    								
    		4)RETURN VALUE
    		       All of these functions return 0 on success; on error, the value of the semaphore is left unchanged, -1 is  returned,  and
    		       errno is set to indicate the error.
    
    
    5.sem_post()  //(对比pthread_mutex_unlock)
    		man sem_post
    		1)NAME
    		       sem_post - unlock a semaphore
    		
    		2)SYNOPSIS
    		       #include <semaphore.h>
    		
    		       int sem_post(sem_t *sem);
    		
    		       Link with -pthread.
    		3)RETURN VALUE
    		       sem_post() returns 0 on success; on error, the value of the semaphore is left unchanged, -1 is returned, and errno is set
    		       to indicate the error.
    
    
    
    
  3. 利用信号量实现生产者消费者模型

    DEMO:
    	https://github.com/Panor520/LinuxCode/tree/master/thread/sem_produce_consumer.c
    	DEMO配合下图看。
    

在这里插入图片描述

十一、线程池

  1. 基础概念

     epoll 实现 client 端和 server 端的连接。
     线程池 实现 server 端高效处理和客户端连接的操作。
     
     线程池的实现利用 条件变量 和 锁 机制。
    
  2. 实现
    DEMO还没来的及写,自行百度

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值