线程笔记

学习笔记(三)之线程:

进程创建,进程的调度较为消耗硬件资源,进程切换时会涉及到多个硬件资源的切换c++


线程本质是带有时间片的函数(模块化代码,多个函数相对独立)编程


线程共享资源:
共享进程空间0~3G空间
PIDide

线程独立的资源:
线程的栈区独立
PC指针
线程errno独立
线程编号相互独立模块化

注:不能返回线程空间内的地址函数

安装线程库:
sudo apt-get install manpages-posix-dev
sudo apt-get install manpages-posixpost

线程编程:
注:
1.添加#include <pthread.h>
2.编译时连接线程库 -lpthread
3.线程中慎用exit函数学习

线程建立:本质是线程调用
pthread_create
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
参数:1.pthread_create成功执行时能够获取线程编号 准备pthread_t 变量 取地址放入;2.线程属性设置 填NULL表示默认属性
3.被调用的线程函数的入口地址 void * 线程名(void *);4.用于给第三个参数传参 不须要填NULL
功能:线程调用函数
返回值:成功返回0,失败返回错误号,并设置errno号ui

线程阻塞函数 相似进程中的waitpid(pid)
pthread_join
int pthread_join(pthread_t thread, void **retval);
功能:阻塞等待指定线程退出
参数:1.线程号 2.接收pthread_exit返回的信息 定义一个void* p &p放入,不关心填NULL
返回值:成功返货0,失败返回errno号spa

线程退出 相似进程中的exit
pthread_exit
void pthread_exit(void *retval);
功能:结束调用的线程,返回的一个地址(用于记录信息的首地址,不使用填NULL)线程

线程取消
pthread_cancel
int pthread_cancel(pthread_t thread);
功能:将指定线程退出

 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <stdlib.h>
 4 pthread_t tid1,tid2;
 5 int i = 0;
 6 int a,b;
 7 
 8 
 9 void *fun_a(void *arg)
10 {
11     while(1)
12     {
13         i++;
14         a = i;
15         b = a;
16     }
17     pthread_exit(NULL);
18 }
19 
20 void *fun_b(void *arg)
21 {
22     while(1)
23     {
24         if(a != b)
25         {
26             printf("i:%d a:%d b:%d\n",i,a,b);
27         }
28     }
29     pthread_exit(NULL);
30 }
31 
32 int main(int argc, const char *argv[])
33 {
34     int ret = 0;
35     ret = pthread_create(&tid1,NULL,fun_a,NULL);
36     if(ret != 0)
37     {
38         fprintf(stderr,"fail to create pthread1:%d\n",ret);
39         exit(1);
40     }
41     pthread_create(&tid2,NULL,fun_b,NULL);
42 
43 
44     pthread_join(tid1,NULL);
45     pthread_join(tid2,NULL);
46 
47     return 0;
48 }
pthread1
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 
 4 pthread_t tid1,tid2;
 5 
 6 //线程A:
 7 void *fun1(void * arg)
 8 {
 9     if(arg != NULL)
10     {
11         printf("pthread1_arg:%s\n",(char *)arg);
12     }
13     printf("i'm pthread_1!\n");
14     pthread_exit("hehehe");
15 }
16 
17 
18 //线程B:
19 void *fun2(void * arg)
20 { 
21     if(arg != NULL)
22     {
23         printf("pthread2_arg:%s\n",(char *)arg);
24     }
25     printf("i'm pthread_2!\n");
26     pthread_exit("heiheihei");
27 }
28 
29 
30 
31 int main(int argc, const char *argv[])
32 {
33      
34     char *s1 = "zhangyaqi meimeimei";
35     char *s2 = "jiangtiti meimeimei";
36     //线程调用
37     pthread_create(&tid1,NULL,fun1,s1);
38     pthread_create(&tid2,NULL,fun2,s2);
39 
40     char *ret1 = NULL;
41     char *ret2 = NULL;
42 
43     //阻塞主线程等待全部子线程退出
44     pthread_join(tid1,(void **)&ret1);
45     pthread_join(tid2,(void **)&ret2);
46 
47     printf("pthread1_exit:%s\n",ret1);
48     printf("pthread2_exit:%s\n",ret2);
49 
50 
51     return 0;
52 }
pthread2
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <unistd.h>
 4 
 5 pthread_t tid1,tid2,tid3;
 6 
 7 //线程A
 8 void *fun_a(void *arg)
 9 {
10     while(1)
11     {
12         printf("i'm pthread_a!\n");
13         sleep(1);
14     }
15     pthread_exit(NULL);
16 }
17 //线程B
18 void *fun_b(void *arg)
19 {
20     while(1)
21     {
22         printf("i'm pthread_b!\n");
23         sleep(1);
24     }
25     pthread_exit(NULL);
26 }
27 //线程C
28 void *fun_c(void *arg)
29 {
30     sleep(10);
31     pthread_cancel(tid1);
32     pthread_cancel(tid2);
33 
34     pthread_exit(NULL);
35 }
36 
37 int main(int argc, const char *argv[])
38 {
39     pthread_create(&tid1,NULL,fun_a,NULL);
40     pthread_create(&tid2,NULL,fun_b,NULL);
41     pthread_create(&tid3,NULL,fun_c,NULL);
42 
43     pthread_join(tid1,NULL);
44     pthread_join(tid2,NULL);
45     pthread_join(tid3,NULL);
46 
47 
48 
49     return 0;
50 }
线程取消

 

线程同步和互斥:
同步:自己也是一种特殊的互斥
互斥:

1.全局变量:
作同步没有问题,互斥时可能会出现问题(最好不要用全局变量作互斥)

 1 #include <stdio.h>
 2 #include <pthread.h>
 3 
 4 pthread_t tida,tidb,tidc;
 5 int leda,ledb,ledc;
 6 
 7 void *pthread_a(void *arg)
 8 {
 9     while(1)
10     {
11         if(leda == 1)
12         {
13             leda--;
14             printf("i'm pthread_a!\n");
15             ledb++;
16         }
17     }
18     pthread_exit(NULL);
19 }
20 
21 void *pthread_b(void *arg)
22 {
23     while(1)
24     {
25         if(ledb == 1)
26         {
27             ledb--;
28             printf("i'm pthread_b!\n");
29             ledc++;
30         }
31     }
32     pthread_exit(NULL);
33 }
34 
35 void *pthread_c(void *arg)
36 {
37     while(1)
38     {
39         if(ledc == 1)
40         {
41             ledc--;
42             printf("i'm pthread_c!\n");
43             leda++;
44         }
45     }
46     pthread_exit(NULL);
47 }
48 
49 
50 
51 int main(int argc, const char *argv[])
52 {
53     //初始化灯
54     leda = 1;
55     ledb = 0;
56     ledc = 0;
57 
58     pthread_create(&tida,NULL,pthread_a,NULL);    
59     pthread_create(&tidb,NULL,pthread_b,NULL);    
60     pthread_create(&tidc,NULL,pthread_c,NULL);    
61 
62     pthread_join(tida,NULL);
63     pthread_join(tidb,NULL);
64     pthread_join(tidc,NULL);
65 
66     return 0;
67 }
全局变量做同步
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <stdlib.h>
 4 pthread_t tid1,tid2;
 5 volatile int flag;
 6 
 7 
 8 void *fun_a(void *arg)
 9 {
10     while(1)
11     {
12         if(flag == 1)
13         {
14             flag--;
15             printf("i'm pthread_a!\n");
16             printf("aaaaaaaaaaaaaa\n");
17             flag++;    
18         }
19     }
20     pthread_exit(NULL);
21 }
22 
23 void *fun_b(void *arg)
24 {
25     while(1)
26     {
27         if(flag == 1)
28         {
29             flag--;
30             printf("i'm pthread_b!\n");
31             printf("bbbbbbbbbbbbbb\n");
32             flag++;
33         }
34     }
35     pthread_exit(NULL);
36 }
37 
38 int main(int argc, const char *argv[])
39 {
40     flag = 1;
41     int ret = 0;
42     ret = pthread_create(&tid1,NULL,fun_a,NULL);
43     if(ret != 0)
44     {
45         fprintf(stderr,"fail to create pthread1:%d\n",ret);
46         exit(1);
47     }
48     pthread_create(&tid2,NULL,fun_b,NULL);
49 
50 
51     pthread_join(tid1,NULL);
52     pthread_join(tid2,NULL);
53 
54     return 0;
55 }
全局变量做互斥

 

2.信号量
sem_init 信号量初始化
int sem_init(sem_t *sem, int pshared, unsigned int value);
参数:1.sem_init成功执行时获取对应的信号量编号;  2.决定该信号量用于线程仍是进程 填0表示用于线程;3.信号量的初始值
功能:建立信号量,并设置初始值
返回值:成功返回0,失败返回-1,并设置errno号

sem_wait p操做
int sem_wait(sem_t *sem);
参数:1.信号量地址
功能:对指定信号量执行-1操做,若是信号量值为0,则阻塞等待信号量值>0
返回值:成功返回0,失败返回-1,并设置errno号

sem_post v操做
int sem_post(sem_t *sem);
参数:1.信号量地址
功能:对指定信号量进行+1操做
返回值:成功返回0,失败返回-1,并设置errno号

sem_destroy
int sem_destroy(sem_t *sem);
参数:1.信号量的地址
功能:销毁指定信号量
返回值:成功返回0,失败返回-1,并设置errno号

 1 #include <stdio.h>
 2 #include <semaphore.h>
 3 #include <pthread.h>
 4 
 5 sem_t sem1,sem2,sem3;
 6 pthread_t tid1,tid2,tid3;
 7 
 8 void *pthread_a(void *arg)
 9 {
10     while(1)
11     {
12         sem_wait(&sem1);
13         printf("i'm pthread_a!\n");
14         sem_post(&sem2);
15     }
16     pthread_exit(NULL);
17 }
18 
19 void *pthread_b(void *arg)
20 {
21     while(1)
22     {
23         sem_wait(&sem2);
24         printf("i'm pthread_b!\n");
25         sem_post(&sem3);
26     }
27     pthread_exit(NULL);
28 }
29 
30 void *pthread_c(void *arg)
31 {
32     while(1)
33     {
34         sem_wait(&sem3);
35         printf("i'm pthread_c!\n");
36         sem_post(&sem1);
37     }
38     pthread_exit(NULL);
39 }
40 
41 int main(int argc, const char *argv[])
42 {
43     //初始化
44     sem_init(&sem1,0,1);
45     sem_init(&sem2,0,0);
46     sem_init(&sem3,0,0);
47 
48     //调用线程
49     pthread_create(&tid1,NULL,pthread_a,NULL);
50     pthread_create(&tid2,NULL,pthread_b,NULL);
51     pthread_create(&tid3,NULL,pthread_c,NULL);
52 
53 
54 
55     //线程阻塞
56     pthread_join(tid1,NULL);
57     pthread_join(tid2,NULL);
58     pthread_join(tid3,NULL);
59 
60 
61     //销毁信号量
62     sem_destroy(&sem1);
63     sem_destroy(&sem2);
64     sem_destroy(&sem3);
65     return 0;
66 }
信号量做同步
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <semaphore.h>
 4 
 5 pthread_t tid1,tid2,tid3;
 6 sem_t sem1; 
 7 
 8 
 9 void *pthread_a(void *arg)
10 {
11     while(1)
12     {
13         sem_wait(&sem1);//阻塞等待  若是sem>0 则-1
14         printf("i'm pthread_a!\n");
15         sem_post(&sem1);//sem +1
16     }
17     pthread_exit(NULL);
18 }
19 
20 
21 void *pthread_b(void *arg)
22 {
23     while(1)
24     {
25         sem_wait(&sem1);
26         printf("i'm pthread_b!\n");
27         sem_post(&sem1);
28     }
29     pthread_exit(NULL);
30 }
31 
32 
33 void *pthread_c(void *arg)
34 {
35     while(1)
36     {
37         sem_wait(&sem1);
38         printf("i'm pthread_c!\n");
39         sem_post(&sem1);
40     }
41     pthread_exit(NULL);
42 }
43 
44 
45 int main(int argc, const char *argv[])
46 {
47     
48     //建立并初始化信号量
49     sem_init(&sem1,0,1);    
50 
51     pthread_create(&tid1,NULL,pthread_a,NULL);
52     pthread_create(&tid2,NULL,pthread_b,NULL);
53     pthread_create(&tid3,NULL,pthread_c,NULL);
54 
55 
56     pthread_join(tid1,NULL);
57     pthread_join(tid2,NULL);
58     pthread_join(tid3,NULL);
59 
60     //销毁信号量
61     sem_destroy(&sem1);
62 
63 
64     return 0;
65 }
信号量做互斥

 

3.互斥锁 实现代码块之间的互斥
pthread_mutex_init 建立锁
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
参数:1.当pthread_mutex_init成功执行后获取锁号 2.锁的属性 填NULL,按默认属性
返回值:成功返回0,失败返回错误号

pthread_mutex_lock 上锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
参数:1.锁号的地址
返回值:成功返回0,失败返回错误号

pthread_mutex_unlock 解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
参数:1.锁号的地址
返回值:成功返回0,失败返回错误号

pthread_mutex_destroy 销毁锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
参数:1.锁号的地址
返回值:成功返回0,失败返回错误号

 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <stdlib.h>
 4 pthread_t tid1,tid2;
 5 int i = 0;
 6 int a,b;
 7 pthread_mutex_t lock;
 8 
 9 void *fun_a(void *arg)
10 {
11     while(1)
12     {
13         //上锁
14         pthread_mutex_lock(&lock);
15         i++;
16         a = i;
17         b = a;
18         //解锁
19         pthread_mutex_unlock(&lock);
20     }
21     pthread_exit(NULL);
22 }
23 
24 void *fun_b(void *arg)
25 {
26     while(1)
27     {
28         pthread_mutex_lock(&lock);
29         if(a != b)
30         {
31             printf("i:%d a:%d b:%d\n",i,a,b);
32         }
33         pthread_mutex_unlock(&lock);
34     }
35     pthread_exit(NULL);
36 }
37 
38 int main(int argc, const char *argv[])
39 {
40     //建立锁
41     pthread_mutex_init(&lock,NULL);
42 
43     int ret = 0;
44     ret = pthread_create(&tid1,NULL,fun_a,NULL);
45     if(ret != 0)
46     {
47         fprintf(stderr,"fail to create pthread1:%d\n",ret);
48         exit(1);
49     }
50     pthread_create(&tid2,NULL,fun_b,NULL);
51 
52 
53     pthread_join(tid1,NULL);
54     pthread_join(tid2,NULL);
55 
56     //销毁锁
57     pthread_mutex_destroy(&lock);
58     return 0;
59 }
互斥锁

 


4.条件变量
pthread_cond_init 条件变量的初始化
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
参数:1.pthread_cond_init成功执行时获取条件变量编号 2.条件变量的属性 填NULL默认属性
返回值:成功返回0,失败返回错误号

pthread_cond_signal
int pthread_cond_signal(pthread_cond_t *cond);

pthread_cond_broadcast
int pthread_cond_broadcast(pthread_cond_t *cond);

pthread_cond_wait 解锁->等待->上锁
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
参数:1.条件变量编号 2.锁号
返回值:成功返回0,失败返回错误号

pthread_cond_destroy 销毁信号量
int pthread_cond_destroy(pthread_cond_t *cond);
参数:1.条件变量编号的地址
返回值:成功返回0,失败返回错误号

 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <strings.h>
 4 #include <stdlib.h>
 5 
 6 pthread_mutex_t lock;
 7 
 8 pthread_cond_t cond;
 9 
10 pthread_t tid1,tid2,tid3;
11 
12 char buf[128];
13 
14 //线程A  
15 void *fun_a(void *arg)
16 {
17     while(1)
18     {
19         bzero(buf,sizeof(buf));
20         printf("(pthread_a)please input something:\n");
21         fgets(buf,sizeof(buf),stdin);    
22         //pthread_cond_signal(&cond);
23         pthread_cond_broadcast(&cond);
24         sleep(1);
25     }
26     pthread_exit(NULL);
27 }
28 
29 //线程B
30 void *fun_b(void *arg)
31 {
32     while(1)
33     {
34         pthread_mutex_lock(&lock);
35 //        printf("i'm pthread_b!\n");
36 
37         pthread_cond_wait(&cond,&lock);
38         printf("pthread_b buf:%s\n",buf);
39         if(strncmp(buf,"quit",4) == 0)
40         {
41             exit(0);
42         }
43 
44         pthread_mutex_unlock(&lock);
45     }
46     pthread_exit(NULL);
47 }
48 
49 
50 //线程C
51 void *fun_c(void *arg)
52 {
53     while(1)
54     {
55         pthread_mutex_lock(&lock);
56 //        printf("i'm pthread_c!\n");
57 
58         pthread_cond_wait(&cond,&lock);
59         printf("pthread_c buf:%s\n",buf);
60         if(strncmp(buf,"quit",4) == 0)
61         {
62             exit(0);
63         }
64 
65         pthread_mutex_unlock(&lock);
66     }
67     pthread_exit(NULL);
68 }
69 
70 int main(int argc, const char *argv[])
71 {
72     //建立锁
73     pthread_mutex_init(&lock,NULL);
74     
75     //建立条件变量
76     pthread_cond_init(&cond,NULL);
77 
78     //线程调用
79     pthread_create(&tid1,NULL,fun_a,NULL);
80     pthread_create(&tid2,NULL,fun_b,NULL);
81     pthread_create(&tid3,NULL,fun_c,NULL);
82 
83     //线程阻塞
84     pthread_join(tid1,NULL);
85     pthread_join(tid2,NULL);
86     pthread_join(tid3,NULL);
87 
88     //回收锁
89     pthread_mutex_destroy(&lock);
90 
91     //回收条件变量
92     pthread_cond_destroy(&cond);
93 
94     return 0;
95 }
条件变量
相关文章
相关标签/搜索