1.1 线程同步
因为多线程共享进程的资源,在访问共享的资源时,就有可能出现互相覆盖的情况,叫共享数据冲突。解决共享数据冲突的技术叫线程同步,解决方案就是把共享资源的访问代码由并行改为串行,其他代码无所谓。线程同步会降低线程的效率,因此使用时不是范围越大越好。
互斥锁/互斥量就是其中的一种方案。我们可以在访问共享资源时加上互斥锁,访问共享资源结束后释放互斥锁,就可以把并行改为串行。确保只有一个进程访问。互斥锁是线程规范的一个组成部分。
1.2 互斥量
互斥量的使用步骤:
1 声明互斥量
pthread_mutex_t lock;
2 初始化互斥量
pthread_mutex_init(&lock,0);
或者在声明的同时初始化:
pthread_mutex_t lock=PHTREAD_MUTEX_INITIALIZER;
3 加锁
pthread_mutex_lock(&lock);
4 访问,使用,读写
5 解锁
pthread_mutex_unlock(&lock);
6 销毁锁(释放资源)
pthread_mutex_destroy(&lock);
#include<stdio.h>
#include<pthread.h>
char *data[5];//数组,存储名字
int size = 0;//当前人数,数组下标
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//1
void *task(void *p)
{
pthread_mutex_lock(&lock);//2
data[size] = (char *)p;
sleep(1);
size++;
pthread_mutex_unlock(&lock);//3
}
int main()
{
data[size] = "zhangfei";
size++;
pthread_t id1,id2;
pthread_create(&id1,0,task,"guanyu");
pthread_create(&id2,0,task,"zhaoyun");
pthread_join(id1,0);
pthread_join(id2,0);
pthread_mutex_destroy(&lock);//5
int i;
for (i = 0;i < size;i++)
{
printf("%s\n",data[i]);
}
}
1.3信号量(semaphore)
信号量是一个计数器,用来控制访问临界资源的线程最大并行数量。当信号量的初始值为1时,效果等同于互斥量。
信号量不是最早的POSIX线程相关规范,因此信号量相关定义是在semaphore.h中。semaphore.h中定义的信号量,既可以用于线程,又可以用于进程。
信号量的使用步骤:
1 定义信号量 sem_t sem;
2 初始化信号量 sem_init(&sem,0,计数初始值)
第二个参数为0,代表用于线程计数,其他值代表进程计数(进程计数目前Linux不支持)。
3 获取信号量(计数减1)
sem_wait(&sem);
4 读写资源
5 释放信号量(计数加1)
sem_post(&sem);
6 删除信号量 sem_destroy(&sem);
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
char* data[5];//数组,存储名字
int size = 0;//当前人数,数组下标
sem_t sem;//pthread_mutex_t lock;//1
void* task(void* p)
{
sem_wait(&sem);
//pthread_mutex_lock(&lock);//3
data[size] = (char*)p;//4
sleep(1);
size++;
sem_post(&sem);
//pthread_mutex_unlock(&lock);//5
}//练习:用信号量实现相同的效果
int main()
{
sem_init(&sem,0,1);
//pthread_mutex_init(&lock,0);//2
data[size] = "zhangfei";
size++;
pthread_t id1,id2;
pthread_create(&id1,0,task,"guanyu");
pthread_create(&id2,0,task,"zhaoyun");
pthread_join(id1,0);pthread_join(id2,0);
//pthread_mutex_destroy(&lock);//6
sem_destroy(&sem);
int i;
for(i=0;i<size;i++)
{
printf("%s\n",data[i]);
}
}
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <time.h>
//模拟访问某资源的最大连接数控制
sem_t sem;
void* task(void* p)
{
int i = (int)p;
printf("第%d个线程开始运行\n",i);
sem_wait(&sem);//计数-1,如果计数已经为0
printf("第%d线程连接成功\n",i);//阻塞等待
srand(time(0));
int res = rand()%10;
sleep(res);
printf("第%d个线程连接结束,释放资源\n",i);
sem_post(&sem);
}
int main()
{
sem_init(&sem,0,10);//最多同时连接10个
int i;
for(i=1;i<21;i++)
{
pthread_t id;
pthread_create(&id,0,task,(void*)i);
}
while(1);
}
“`