1. 线程
1.1 线程定义
线程是进程内部的一条执行序列或执行路径,一个进程可以包含多条线程;线程是资源调度的基本单位。 进程:一个正在运行的程序,进程是资源分配的基本单位。
1.2 线程的实现方式
在操作系统中,线程的实现有以下三种方式: ? 内核级线程:创建开销较大,可以利用多处理器资源,可能实现并行 ? 用户级线程:创建更多数目线程,创建开销较少;缺点:无法利用多个处理器,只能实现并发 ? 组合级线程:既可以利用多个处理器资源,又可以创建多数量线程。 Linux系统中线程的实现 内核级线程 Linux把所有的线程都当作进程来实现,内核没有准备特别的调度算法或是定义特别的数据结构来表明线程。线程仅仅被视为一个与其他进程共享某些资源的进程。
1.3 进程与线程的区别
? 进程是资源分配的最小单位,线程是 CPU 调度的最小单位 ? 进程有自己的独立地址空间,线程共享进程中的地址空间 ? 进程的创建消耗资源大,线程的创建相对较小 ? 进程的切换开销大,线程的切换开销相对较小
1.4 线程创建
pthread_create() 创建线程 pthread_join() 等待线程结束 pthread_exit() 退出线程
1.5 线程
- 并发运行
- 同步线程
- 线程安全
1.6 代码
main.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<pthread.h>
6
7 void*fun(void*arg)
8 {
9 for(int i=0;i<5;i++)
10 {
11 printf("fun run\n");
12 sleep(1);
13 }
14 pthread_exit("fun over");
15 }
16 int main()
17 {
18 pthread_t id;
19 pthread_create(&id,NULL,fun,NULL);
20
21 for(int i=0;i<5;i++)
22 {
23 printf("main run\n");
24 sleep(1);
25 }
26 char*s=NULL;
27 pthread_join(id,(void**)&s);
28 printf("s=%s\n",s);
29 exit(0);
30 }
运行结果 test.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<pthread.h>
6
7 void*fun(void*arg)
8 {
9 int index=*(int*)arg;
10 for(int i=0;i<3;i++)
11 {
12 printf("index=%d\n",index);
13 sleep(1);
14 }
15 }
16 int main()
17 {
18 pthread_t id[5];
19 int i=0;
20 for(;i<5;i++)
21 {
22 pthread_create(&id[i],NULL,fun,(void*)&i);
23 }
24 for(i=0;i<5;i++)
25 {
26 pthread_join(id[i],NULL);
27 }
28 exit(0);
29 }
运行结果 test.c(修改版) 运行结果(按照顺序执行) thread.c 运行结果
1.7 例题
对于变量i在多个线程中进行++操作,一个程序100次,另一个程序100次,求一共多少个值?
答案 <= 200次 代码转化为指令
1.8 进行信号量设置后,进程不存在并行
thread.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<pthread.h>
6 #include<semaphore.h>
7 int m_index=1;
8 sem_t sem;
9 void*fun(void*arg)
10 {
11 for(int i=0;i<1000;i++)
12 {
13 sem_wait(&sem);
14 printf("m_index=%d\n",m_index++);
15 sem_post(&sem);
16 }
17 }
18 int main()
19 {
20 sem_init(&sem,0,1);
21 pthread_t id[5];
22 for(int i=0;i<5;i++)
23 {
24 pthread_create(&id[i],NULL,fun,NULL);
25 }
26
27 for(int i=0;i<5;i++)
28 {
29 pthread_join(id[i],NULL);
30 }
31 sem_destroy(&sem);
32 exit(0);
33 }
运行结果
1.9 信号量控制按照顺序打印A,B,C
main.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<pthread.h>
6 #include<semaphore.h>
7
8 sem_t sem1,sem2,sem3;
9 void* fun1(void* arg)
10 {
11 for(int i=0;i<5;i++)
12 {
13 sem_wait(&sem1);
14 printf("A");
15 fflush(stdout);
16 sem_post(&sem2);
17 }
18 }
19
20 void* fun2(void* arg)
21 {
22 for(int i=0;i<5;i++)
23 {
24 sem_wait(&sem2);
25 printf("B");
26 fflush(stdout);
27 sem_post(&sem3);
28 }
29 }
30
31 void* fun3(void* arg)
32 {
33 for(int i=0;i<5;i++)
34 {
35 sem_wait(&sem3);
36 printf("C");
37 fflush(stdout);
38 sem_post(&sem1);
39 }
40 }
41
42 int main()
43 {
44 sem_init(&sem1,0,1);
45 sem_init(&sem2,0,0);
46 sem_init(&sem3,0,0);
47
48 pthread_t id1,id2,id3;
49 pthread_create(&id1,NULL,fun1,NULL);
50 pthread_create(&id2,NULL,fun2,NULL);
51 pthread_create(&id3,NULL,fun3,NULL);
52
53 pthread_join(id1,NULL);
54 pthread_join(id2,NULL);
55 pthread_join(id3,NULL);
56
57 sem_destroy(&sem1);
58 sem_destroy(&sem2);
59 sem_destroy(&sem3);
60
61 exit(0);
62 }
运行结果 test.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<pthread.h>
6 #include<semaphore.h>
7
8 pthread_rwlock_t rwlock;
9
10 void*fun1(void*arg)
11 {
12 for(int i=0;i<5;i++)
13 {
14 pthread_rwlock_rdlock(&rwlock);
15 printf("a read start...\n");
16 int n=rand() % 3;
17 sleep(n);
18 printf("a read end...\n");
19 pthread_rwlock_unlock(&rwlock);
20 n=rand() % 3;
21 sleep(n);
22 }
23 }
24 void*fun2(void*arg)
25 {
26 for(int i=0;i<5;i++)
27 {
28 pthread_rwlock_rdlock(&rwlock);
29 printf("b read start...\n");
30 int n=rand() % 3;
31 sleep(n);
32 printf("b read end...\n");
33 pthread_rwlock_unlock(&rwlock);
34 n=rand() % 3;
35 sleep(n);
36 }
37 }
38 void*fun3(void*arg)
39 {
40 for(int i=0;i<5;i++)
41 {
42 pthread_rwlock_wrlock(&rwlock);
43 printf("----write start----\n");
44 int n=rand() % 3;
45 sleep(n);
46 printf("----write end----\n");
47 pthread_rwlock_unlock(&rwlock);
48 n=rand() % 3;
49 sleep(n);
50 }
51 }
52 int main()
53 {
54 pthread_rwlock_init(&rwlock,NULL);
55 pthread_t id1,id2,id3;
56 pthread_create(&id1,NULL,fun1,NULL);
57 pthread_create(&id2,NULL,fun2,NULL);
58 pthread_create(&id3,NULL,fun3,NULL);
59
60 pthread_join(id1,NULL);
61 pthread_join(id2,NULL);
62 pthread_join(id3,NULL);
63
64 pthread_rwlock_destroy(&rwlock);
65 exit(0);
66 }
运行结果
1.10 条件变量
1.10.1 函数
pthread_cond_wait() 把线程存放到等待队列 pthread_cond_signal() 唤醒单个线程 pthread_cond_broadcast() 唤醒所有进程
1.11 唤醒线程
cond.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<pthread.h>
6 #include<semaphore.h>
7
8 pthread_mutex_t mutex;
9 pthread_cond_t cond;
10
11 void*funa(void*arg)
12 {
13 while(1)
14 {
15 char*s=(char*)arg;
16 pthread_mutex_lock(&mutex);
17 pthread_cond_wait(&cond,&mutex);
18 pthread_mutex_unlock(&mutex);
19
20 if(strncmp(s,"end",3)==0)
21 {
22 break;
23 }
24 printf("a:%s\n",s);
25 }
26 printf("funa over\n");
27 }
28
29 void*funb(void*arg)
30 {
31 while(1)
32 {
33 char*s=(char*)arg;
34 pthread_mutex_lock(&mutex);
35 pthread_cond_wait(&cond,&mutex);
36 pthread_mutex_unlock(&mutex);
37
38 if(strncmp(s,"end",3)==0)
39 {
40 break;
41 }
42 printf("b:%s\n",s);
43 }
44 printf("funb over\n");
45 }
46
47 int main()
48 {
49 pthread_mutex_init(&mutex,NULL);
50 pthread_cond_init(&cond,NULL);
51
52 char buff[128]={0};
53 pthread_t ida,idb;
54
55 pthread_create(&ida,NULL,funa,buff);
56 pthread_create(&idb,NULL,funb,buff);
57
58 while(1)
59 {
60 fgets(buff,127,stdin);
61
62 if(strncmp(buff,"end",3)==0)
63 {
64 pthread_cond_broadcast(&cond);
65 break;
66 }
67 else
68 {
69 pthread_cond_signal(&cond);
70 }
71 }
72
73 pthread_join(ida,NULL);
74 pthread_join(idb,NULL);
75
76 pthread_cond_destroy(&cond);
77 pthread_mutex_destroy(&mutex);
78 }
运行结果
|