Linux--线程同步
创始人
2025-05-30 06:35:02

目录

一、概念:

二、线程方式:

1.用户级线程:

2.内核线程:

3.组合线程:

三、线程在Linux中的实现

四、线程同步

1.信号量 :

//不随机打印,按照ABC的顺序打印

​编辑

 //接口

//代码

 //运行结果:

2.互斥锁:

 //1.代码:

//运行结果: 

 //2.互斥锁接口:

//3.加锁代码

//运行结果:

3.条件变量:

//代码:

//运行结果:

 ​编辑

4.读写锁:

//接口

 //代码

//运行结果


一、概念:

线程:进程内部的一条执行路径(序列)

进程:一个正在运行的程序

二、线程方式:

1.用户级线程:

用户空间的代码管理线程的创建、调度等等,开销小但是由于是用户自己创建的与内核无关,所以内核无法感知到这类线程的存在,认为只有一个线程存在,无法利用多个处理器。

2.内核线程:

能够被调度到不同处理器上,使他们同时进行;开销相对于用户及线程大,可以利用多个处理器

3.组合线程:

 处于以上两者之间

三、线程在Linux中的实现

四、线程同步

1.信号量 :

//不随机打印,按照ABC的顺序打印

 //接口

//代码

#include
#include
#include
#include
#include
#includesem_t sema;
sem_t semb;
sem_t semc;void* funa(void* arg)
{for(int i=0;i<5;i++){sem_wait(&sema);//ps1;printf("A");fflush(stdout);sem_post(&semb);//vs2}
}void* funb(void* arg)
{for(int i=0;i<5;i++){sem_wait(&semb);//psb;printf("B");fflush(stdout);sem_post(&semc);//vsc}
}void * func(void *arg)
{for(int i=0;i<5;i++){sem_wait(&semc);printf("C");fflush(stdout);sem_post(&sema);}
}int main()
{sem_init(&sema,0,1);sem_init(&semb,0,0);sem_init(&semc,0,0);pthread_t id1,id2,id3;pthread_create(&id1,NULL,funa,NULL);pthread_create(&id2,NULL,funb,NULL);pthread_create(&id3,NULL,func,NULL);pthread_join(id1,NULL);pthread_join(id2,NULL);pthread_join(id3,NULL);sem_destroy(&sema);sem_destroy(&semb);sem_destroy(&semc);exit(0);
}

 //运行结果:

 

2.互斥锁:

能完成信号量的一个子集(信号量初始值为1的类型,有可能阻塞类似p操作为0)

 //1.代码:

#include
#include
#include
#include
#includevoid* fun1(void* arg)
{for(int i=0;i<5;i++){   printf("A");//开始使用打印机fflush(stdout);//标准输出,刷新int n=rand()%3;//随即睡眠三秒以内的时间sleep(n);printf("A");//使用结束fflush(stdout);sleep(n)}   
}void* fun2(void* arg)
{for(int i=0;i<5;i++){   printf("B");//开始使用打印机fflush(stdout);//标准输出,刷新int n=rand()%3;//随即睡眠三秒以内的时间sleep(n);printf("B");//使用结束fflush(stdout);sleep(n);}   
}int main()
{pthread_t id1,id2;pthread_create(&id1,NULL,fun1,NULL);pthread_create(&id2,NULL,fun2,NULL);pthread_join(id1,NULL);  pthread_join(id2,NULL);
}

//运行结果: 

//如何让运行结果达到我们想要的成对出现?

 //2.互斥锁接口:

//init

 //lock、unlock

 //destroy

//3.加锁代码

#include
#include
#include
#include
#includepthread_mutex_t mutex;//定义一个锁void* fun1(void* arg)
{for(int i=0;i<5;i++){pthread_mutex_lock(&mutex);//可能阻塞printf("A");//开始使用打印机fflush(stdout);//标准输出,刷新int n=rand()%3;//随即睡眠三秒以内的时间sleep(n);printf("A");//使用结束n=rand()%3;fflush(stdout);pthread_mutex_unlock(&mutex);//如果忘记解锁会一直阻塞sleep(n);}
}void* fun2(void* arg)
{for(int i=0;i<5;i++){pthread_mutex_lock(&mutex);printf("B");//开始使用打印机fflush(stdout);//标准输出,刷新int n=rand()%3;//随即睡眠三秒以内的时间sleep(n);printf("B");//使用结束pthread_mutex_unlock(&mutex);n=rand()%3;sleep(n);}
}int main()
{pthread_mutex_init(&mutex,NULL);pthread_t id1,id2;pthread_create(&id1,NULL,fun1,NULL);pthread_create(&id2,NULL,fun2,NULL);pthread_join(id1,NULL);pthread_join(id2,NULL);pthread_mutex_destroy(&mutex);exit(0);
}

//运行结果:

3.条件变量:

提供线程间的通知机制

 

 //使用条件变量还需要互斥锁

//代码:

#include
#include
#include
#include
#includepthread_mutex_t mutex;
pthread_cond_t cond;void*funa(void*arg)
{char* s=(char*)arg;while(1){   pthread_mutex_lock(&mutex);//上锁pthread_cond_wait(&cond,&mutex);//解锁,上锁pthread_mutex_unlock(&mutex);//解锁if(strncmp(s,"end",3)==0){break;}else{printf("funa: %s\n",s);}}   }void* funb(void* arg)
{char* s=(char*) arg;while(1){   pthread_mutex_lock(&mutex);pthread_cond_wait(&cond,&mutex);pthread_mutex_unlock(&mutex);if(strncmp(s,"end",3)==0){break;}else{printf("funb: %s\n",s);}}   
}int main()
{char buff[128]={0};pthread_t id1,id2;pthread_create(&id1,NULL,funa,(void*)buff);pthread_create(&id2,NULL,funb,(void*)buff);while(1){   fgets(buff,128,stdin);if(strncmp(buff,"end",3)==0){pthread_cond_broadcast(&cond);//唤醒所有线程break;}else{pthread_cond_signal(&cond);//唤醒一个线程}}   pthread_join(id1,NULL);pthread_join(id2,NULL);pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);exit(0);}

//运行结果:

 

//ab交替读取,读到end,退出 

4.读写锁:

对某个资源既有读也有写

//接口

// man pthread_rwlock_init

//其余接口

 //代码

    for(int i=0;i<10;i++){   pthread_rwlock_rdlock(&lock);printf("fun1 read start--\n");sleep(1);printf("fun1 read end--\n");pthread_rwlock_unlock(&lock);sleep(1);}   
}void* fun2(void* arg)
{for(int i=0;i<5;i++);{   pthread_rwlock_rdlock(&lock);printf("fun2 read start--\n");sleep(2);printf("fun2 read end--\n");pthread_rwlock_unlock(&lock);}   
}void* fun3(void*arg)
{for(int i=0;i<3;i++){   pthread_rwlock_wrlock(&lock);printf("fun3 write start--\n");sleep(3);printf("fun3 write end--\n");pthread_rwlock_unlock(&lock);}   
}int main()
{pthread_rwlock_init(&lock,NULL);pthread_t id1,id2,id3;pthread_create(&id1,NULL,fun1,NULL);pthread_create(&id2,NULL,fun2,NULL);pthread_create(&id2,NULL,fun3,NULL);pthread_join(id1,NULL);pthread_join(id2,NULL);pthread_join(id3,NULL);pthread_rwlock_destroy(&lock);exit(0);
}

//运行结果

 //两个读锁可以同时通过,一旦开始读不能写,一旦开始写不能读,

相关内容

热门资讯

另一个世界的声音【经典3篇】 另一个世界的声音 篇一在我们熟悉的世界中,声音是我们交流和沟通的主要方式之一。我们可以通过语言、音乐...
中考语文答题的技巧【精简3篇... 中考语文答题的技巧 篇一中考作为学生们进入高中的关键一战,语文作为其中最重要的科目之一,对于学生们的...
安徽中考体育总分值迎4连涨(... 安徽中考体育总分值迎4连涨 篇一安徽中考体育总分值迎4连涨近年来,安徽中考体育总分值迎来了4连涨的好...
24家低空企业披露业绩预告:上... 21世纪经济报道记者孙燕 上海报道 低空经济企业陆续交出2025年半年“成绩单”。 截至7月14日,...
中考范文记叙文手写(实用6篇... 中考范文记叙文手写 篇一我的暑假计划今年的暑假即将来临,我早早地做好了暑假计划。我计划在暑假期间充实...