目录
一、概念:
二、线程方式:
1.用户级线程:
2.内核线程:
3.组合线程:
三、线程在Linux中的实现
四、线程同步
1.信号量 :
//不随机打印,按照ABC的顺序打印
编辑
//接口
//代码
//运行结果:
2.互斥锁:
//1.代码:
//运行结果:
//2.互斥锁接口:
//3.加锁代码
//运行结果:
3.条件变量:
//代码:
//运行结果:
编辑
4.读写锁:
//接口
//代码
//运行结果
线程:进程内部的一条执行路径(序列)
进程:一个正在运行的程序
用户空间的代码管理线程的创建、调度等等,开销小但是由于是用户自己创建的与内核无关,所以内核无法感知到这类线程的存在,认为只有一个线程存在,无法利用多个处理器。
能够被调度到不同处理器上,使他们同时进行;开销相对于用户及线程大,可以利用多个处理器
处于以上两者之间
#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);
}
能完成信号量的一个子集(信号量初始值为1的类型,有可能阻塞类似p操作为0)
#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);
}
//如何让运行结果达到我们想要的成对出现?
//init
//lock、unlock
//destroy
#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);
}
提供线程间的通知机制
//使用条件变量还需要互斥锁
#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,退出
对某个资源既有读也有写
// 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);
}
//两个读锁可以同时通过,一旦开始读不能写,一旦开始写不能读,