线程同步

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);
}

“`

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值