用于线程间的同步与互斥-信号量sem

一、线程

首先我们说一下什么是线程。线程是计算机中独立运行的最小单位,在运行时占用很少的系统资源,由于每个线程占用的CPU时间是由系统分配的,因此我们可以把线程看作为系统分配CPU时间的基本单位。在我们用户看来多线程是并发执行的,但是从操作系统的角度来看,对于单核CPU来说各个线程是交替执行的,系统在各个线程之间不停的切换,每个线程只有在系统分配给它的时间内获得cup的控制权,执行线程中的代码。

二、线程的使用

了解了什么是线程之后,我们就可以使用线程,这里我们通过三个函数来对线程进行操作。
头文件:#include
1.创建线程:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
参数:
thread:用来存放线程id号
attr: 线程的属性,一般用NULL
start_routine:函数指针,指线程要做的事情,类似于信号处理函数。
arg:给函数传递的参数,没有可用使用NULL
返回值:
成功:0
失败:errno

举个栗子:
pthread_t thread_A;
pthread_create(&thread_A,NULL,handler_A,NULL)
2.退出线程
void pthread_exit(void *retval);
参数:传递给接收函数的参数,标识退出状态
举个栗子:
pthread_exit((void *)0);
3.阻塞等待接收线程退出状态,并回收资源
int pthread_join(pthread_t thread,void **retval)
参数:
thread 线程号
*retval:不关心一般为NULL
返回值:成功 0 ,失败 errno
举个栗子:
pthread_join(thread_A,NULL);

三、信号量的使用

信号量:也就是操作系统中的PV原子操作,用户线程之间的同步与互斥。本质是一个非负整数计数器,被用来控制 公共资源的访问。
P操作(申请资源):如果有可用资源(信号量值大于0),则占用一个资源(信号量值-1,进入临界区代码),如果没有可用资源(信号量值等于0),则阻塞,直到系统将资源分配给线程。
V操作(释放资源):如果该信号量的等待队列有任务在等待资源,则唤醒一个任务,如果没有则释放信号量。

头文件:#include

1.初始化:int sem_init(sem_t *sem, int pshared, unsigned int value);
参数:
sem:信号量标识
pshared:用于线程间通信, 0
value:信号量的处置,代表可用资源数个数,为了实现互斥现象一般为1.
返回值:成功 0 ,失败 -1.

2.申请资源:int sem_wait(sem_t *sem)
功能:申请资源
参数:sem‘’
返回值:成功0 失败-1

3.释放资源: int sem_post(sem_t *sem); Link with -pthread.
功能:释放资源
参数:sem‘’
返回值:成功0 失败-1

4.销毁信号量 int sem_destroy(sem_t *sem); Link with r -pthread.
功能:释放资源
参数:sem‘’
返回值:成功0 失败-1
下面给大家一个关于线程的青宁的面试题
1、 /编写一个程序,开启三个线程,这三个线程的ID分别是ABC,每个线程将自己的ID在屏幕上打印10遍,/要求输出必须按照ABC的顺序显示,如:ABCABCABC….。

  6 #include 
  7 #include 
  8 #include 
  9 
 10 sem_t sem_A;
 11 sem_t sem_B;
 12 sem_t sem_C;
 13 
 14 void *pthread_A_handler(void)
 15 {
 16     int i;
 17     for(i=0; i<10; i++){
 18         sem_wait(&sem_C);                                                                                                                        
 19         printf("A\n");
 20         sem_post(&sem_A);
 21     }
 22     pthread_exit((void *)0);
 23 }
 24 
 25 void *pthread_B_handler(void)
 26 {
 27     int i;
 28     for(i=0; i<10; i++){
 29         sem_wait(&sem_A);
 30         printf("B\n");
 31         sem_post(&sem_B);
 32     }
 33     pthread_exit((void *)0);
 34 }
 36 void *pthread_C_handler(void)
 37 {
 38     int i;
 39     for(i=0; i<10; i++){
 40         sem_wait(&sem_B);
 41         printf("C\n");
 42         sem_post(&sem_C);
 43     }
 44     pthread_exit((void *)0);
 45 }
 46 int main()
 47 {
 48     pthread_t pthread_A;
 49     pthread_t pthread_B;
 50     pthread_t pthread_C;
 51     int ret;
 52     ret = sem_init(&sem_A,0,0);
 53     if(ret != 0) {
 54         printf("sem_init error\n");                                                                                                              
 55         return 1;
 56     }
 57     ret = sem_init(&sem_B,0,0);
 58     if(ret != 0) {
 59         printf("sem_init error\n");
 60         return 1;
 61     }
 62     ret = sem_init(&sem_C,0,1);
 63     if(ret != 0) {
 64         printf("sem_init error\n");
 65         return 1;
 66     }
 67 
ret = pthread_create(&pthread_A,NULL,pthread_A_handler,NULL);
 69     if(ret != 0) {
 70         printf("pthread_create error\n");
 71         return 1;
 72     }
 73     ret = pthread_create(&pthread_B,NULL,pthread_B_handler,NULL);
 74     if(ret != 0) {
 75         printf("pthread_create error\n");                                                                                                        
 76         return 1;
 77     }
 78     ret = pthread_create(&pthread_C,NULL,pthread_C_handler,NULL);
 79     if(ret != 0) {
 80         printf("pthread_create error\n");
 81         return 1;
 82     }
 83 
 84 
 85     pthread_join(pthread_A,NULL);
 86     pthread_join(pthread_B,NULL);
 87     pthread_join(pthread_C,NULL);
 88     sem_destroy(&sem_A);
 89     sem_destroy(&sem_B);
 90     sem_destroy(&sem_C);
 91 	return 0;
 92 }

你可能感兴趣的:(Linux线程,信号量sem,多线程开发,线程面试题,线程间同步与互斥)