详解线程的时限信号量和排斥锁

  前言:有个难点深感一向会被问道:进度和线程的分别?大概在此以前俺会回答:

  • 进程:能源分配最小单位
  • 线程:轻量级的进度 是系统调治的小不点儿单位 由进度成立多个线程分享进程的能源

  然近期后作者感到一个比如回答的更加好:程序就如静止的列车,进程是运作的列车,线程是运作高铁的每节车厢。

个人感到驾驭远比背些概念性东西更加好。

  一、线程

  经常在一个经过中能够包含若干个线程,当然三个历程中最少有四个线程,不然未有存在的含义。线程能够使用进度所独具的财富,在引进线程的操作系统中,常常都以把进程作为分配能源的主导单位,而把线程作为单身运作和独门调整的宗旨单位,由于线程比进度越来越小,基本上不持有系统财富,故对它的调节所付出的付出就能够小得多,能更加高效的增加系统三个程序间并发试行的档次。

  1、线程相关函数 

  • pthread_create函数

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_ca88官网,attr_t
*attr,
void *(*start_routine) (void *), void *arg);

注:Compile and link with
-pthread.//编译时 要加-lpthread
功效:创立线程
参数1:线程的ID
参数2:NULL
参数3:线程处理函数
参数4: 传递给线程处理函数的参数
中标放回0 战败重临-1

  • pthread_join函数

#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);

意义:以堵塞的主意等待钦定线程 主线程借使施行到此函数
将阻塞等待子线程甘休

  程序1-1演示多个函数用法:

#include"my.h"

void *func(void *p) 
{
    *(int*)p = 10; 
    printf("%d\n",*(int *)p);
}

int main()
{
    int x=100;
    pthread_t id; 
    int ret = pthread_create(&id,NULL,func,&x);
    if(ret<0)
    {   
        perror("pthread_create");
        exit(-1);
    }   
    pthread_join(id,NULL);
    return 0;

}

注:头文件“my.h”为自定义文件,详细的情况请参谋这篇博客:http://www.cnblogs.com/liudw-0215/p/8946879.html  

运转演示如下图:

ca88官网 1

  二、信号量

  能量信号量(Semaphore),不时被叫做随机信号灯,是在多线程碰着下行使的一种配备,
它担负协和各种线程, 以保障它们能够科学、合理的使用公共财富。

  1、实信号量相关函数

  • sem_init函数

sem_t s;

#include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);

格式:sem_init(&s,0,n)
成效:最先化三个复信号量的值为value
参数2:是或不是在进度间使用 一般总是0 表示不在进度间选取
参数3:计数器的最初值

  • sem_wait函数

int sem_wait(sem_t *sem);
把计数器减一 它会等待 直到功率信号量有个非零值才会推行减法操作
假若对值为0的复信号量用sem_wait 那么些函数会等待
直到其余线程增添该复信号量的值 使其不再是0截至
若是对值为2的功率信号量调用sem_wait 线程会继续施行 但实信号量的值会减一。
一经八个线程同有时候在sem_wait调用优质待同多少个信号量变为非0值 那么当时限信号量
被第多少个线程+1 独有一个等候线程初阶对数字信号量-1
接下来继续施行 另多个线程还延续等待。

  • sem_post函数

#include <semaphore.h>

int sem_post(sem_t *sem);

功能:把 计数器+1

  程序2-1介绍时限信号量使用

#include"my.h"

sem_t s;

void *fun(void *p)
{
    int i;
    int *pa = (int *)p;
    for(i=0;i<4;i++)
    {
        sem_wait(&s);//将计数器的值-1 
        pa[i] +=i;
    }
    for(i=0;i<4;i++)
    {
        printf("%-02d",pa[i]);
    }
    printf("\n");
    return  NULL;
}

void *fun1(void *p)
{
    sem_wait(&s);//将计数器的值-1 
    puts("fun1 run!");
    return NULL;
}

int main()
{
    int i=0,ret=0;
    int a[5]={0};
    sem_init(&s,0,0);//设置信号量的值为0
    pthread_t tid[2];
    ret = pthread_create(&tid[0],NULL,fun,a);
    if(ret<0)
    {
        perror("pthread_create");
        exit(-1);
    }
    ret = pthread_create(&tid[1],NULL,fun1,a);
    if(ret<0)
    {
        perror("pthread_create");
        exit(-1);
    }

    for(i=0;i<5;i++)
    {
        sem_post(&s);//将计数器的值+1  
    }

    pthread_join(tid[0],NULL);
    pthread_join(tid[1],NULL);
    return 0;
}

运行演示如下图:

ca88官网 2

  三、互斥锁

  互斥锁: 只要被锁住,其余任何线程都不得以访问被保安的财富

  1、互斥锁相关函数

pthread_mutex_t m;

pthread_mutex_init(&m,NULL) //起头化互斥量
pthread_mutex_lock(&m);//对三个互斥量加锁 假诺互斥量已经加锁
函数会一向等待 等到有线程把那些互斥量解锁后 再去加锁
pthread_mutex_unlock(&m);//对一个互斥量解锁
哪个线程加锁只可以由那一个线程解锁 别的线程不能够 解锁

  程序3-1示范互斥锁应用:

#include"my.h"

pthread_mutex_t m;

void* thread_fun(void  *p)
{
    int i;
    pthread_mutex_lock(&m);//加锁
    for(i=0;i<3;i++)
    {
        printf("PID:%d tid:%lu\n",getpid(),pthread_self());
        sleep(1);
    }
    pthread_mutex_unlock(&m);//解锁
    pthread_exit(NULL);
}

int main()
{
    pthread_mutex_init(&m,NULL);//初始化锁
    int i,ret;
    pthread_t tid[3];
    for(i=0;i<3;i++)
    {
        ret = pthread_create(&tid[i],NULL,thread_fun,NULL);
        if(ret<0)
        {
            printf("pthread_create  %d error\n",i);
            exit(-1);
        }
    }



    for(i=0;i<3;i++)
    {
        pthread_join(tid[i],NULL);
    }
    return 0;
}

  运转演示如下图:

ca88官网 3

小结:首要介绍线程同步的非确定性信号量和互斥锁,将来临时间将特别详细介绍在那之中落到实处原理。

  

相关文章