- 1. 线程
- 1.1 线程定义
- 1.2 线程的实现方式
- 1.3 进程与线程的区别
- 1.4 线程创建
- 1.5 线程
- 1.6 代码
- 1.7 例题
- 1.8 进行信号量设置后,进程不存在并行
- 1.9 信号量控制按照顺序打印A,B,C
- 1.10 条件变量
- 1.10.1 函数
- 1.11 唤醒线程
1. 线程 1.1 线程定义
线程是进程内部的一条执行序列或执行路径,一个进程可以包含多条线程;线程是资源调度的基本单位。
进程:一个正在运行的程序,进程是资源分配的基本单位。
在操作系统中,线程的实现有以下三种方式:
◼ 内核级线程:创建开销较大,可以利用多处理器资源,可能实现并行
◼ 用户级线程:创建更多数目线程,创建开销较少;缺点:无法利用多个处理器,只能实现并发
◼ 组合级线程:既可以利用多个处理器资源,又可以创建多数量线程。
Linux系统中线程的实现
内核级线程
Linux把所有的线程都当作进程来实现,内核没有准备特别的调度算法或是定义特别的数据结构来表明线程。线程仅仅被视为一个与其他进程共享某些资源的进程。
◼ 进程是资源分配的最小单位,线程是 CPU 调度的最小单位
◼ 进程有自己的独立地址空间,线程共享进程中的地址空间
◼ 进程的创建消耗资源大,线程的创建相对较小
◼ 进程的切换开销大,线程的切换开销相对较小
pthread_create() 创建线程 pthread_join() 等待线程结束 pthread_exit() 退出线程
1.5 线程- 并发运行
- 同步线程
- 线程安全
main.c
1 #include2 #include 3 #include 4 #include 5 #include 6 7 void*fun(void*arg) 8 { 9 for(int i=0;i<5;i++) 10 { 11 printf("fun runn"); 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 runn"); 24 sleep(1); 25 } 26 char*s=NULL; 27 pthread_join(id,(void**)&s); 28 printf("s=%sn",s); 29 exit(0); 30 }
运行结果
test.c
1 #include2 #include 3 #include 4 #include 5 #include 6 7 void*fun(void*arg) 8 { 9 int index=*(int*)arg;//获取值 10 for(int i=0;i<3;i++) 11 { 12 printf("index=%dn",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
运行结果
对于变量i在多个线程中进行++操作,一个程序100次,另一个程序100次,求一共多少个值?
答案
<= 200次
代码转化为指令
thread.c
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 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=%dn",m_index++); 15 sem_post(&sem); 16 } 17 } 18 int main() 19 { 20 sem_init(&sem,0,1); 21 pthread_t id[5];//创建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 }
运行结果
main.c
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 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 #include2 #include 3 #include 4 #include 5 #include 6 #include 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 }
运行结果
pthread_cond_wait() 把线程存放到等待队列 pthread_cond_signal() 唤醒单个线程 pthread_cond_broadcast() 唤醒所有进程
1.11 唤醒线程cond.c
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 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:%sn",s); 25 } 26 printf("funa overn"); 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:%sn",s); 43 } 44 printf("funb overn"); 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 }
运行结果



