首先我们说一下什么是线程。线程是计算机中独立运行的最小单位,在运行时占用很少的系统资源,由于每个线程占用的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 }