Linux之————线程通信(二)

续接上一部分线程通信(一)的内容

 线程的同步和互斥:

 进行多线程编程,因为无法知道哪个线程会在哪个时候对共享资源进行操作,因此让如何保护共享资源变得复杂,通过下面这些技术的使用,可以解决

线程之间对资源的竞争:

1. 互斥量Mutex

2. 信号灯Semaphore

3. 条件变量Conditions

 

mutex互斥锁线程控制

互斥锁是用一种简单的加锁方法来控制对共享资源的原子操作。

互斥锁只有两种状态,也就是上锁和解锁,可以把互斥锁看作某种意义上的全局变量。

在同一时刻只能有一个线程掌握某个互斥锁,拥有上锁状态的线程能够对共享资源进行操作。若其他线程希望上锁一个已经被上锁的互斥锁,则该线程就会挂起,直到上锁的线程释放掉互斥锁为止。

互斥锁可以分为快速互斥锁、递归互斥锁和检错互斥锁。

这三种锁的区别主要在于其他未占有互斥锁的线程在希望得到互斥锁时是否需要阻塞等待。

快速锁是指调用线程会阻塞直至拥有互斥锁的线程解锁为止。

递归互斥锁能够成功地返回,并且增加调用线程在互斥上加锁的次数,

而检错互斥锁则为快速互斥锁的非阻塞版本,它会立即返回并返回一个错误信息。

默认属性为快速互斥锁。

互斥锁线程控制

 

线程之间的同步和互斥

Pthread_mutex_init()

函数的作用:互斥锁的初始化

函数的头文件:#include <semaphore.h>

函数的原型:int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr *attr)

函数的参数:

           Mutex:互斥锁

           MutexattrPIHREAD_MUTEX_INITIALIZER 快速互斥锁

函数的返回值:

           成功:返回 0

           出错: 返回 < 0

 

作用:对互斥锁上锁、判断上锁、解锁、清除互斥锁

互斥锁上锁:pthread_mutex_lock(pthread_mutex_t *mutex)

互斥锁判断上锁:pthread_mutex_trylock(pthread_mutex_t *mutex)

互斥锁接锁:pthread_mutex_unlock(pthread_mutex_t *mutex)

消除互斥锁:pthread_mutex_destroy(pthread_mutex_t *mutex)

函数的返回值:

         成功: 0           出错: -1

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define  THREAD_NUM  3
#define  REPEAT_NUM  3
#define  DELAY_TIME_LEVELS  6.0  

pthread_mutex_t mutex;

void *thrd_func(void *arg)
{
    int thrd_num = (int)arg;
    int delay_time =0, count=0;
    int res;
    
    /*线程上锁*/
    res = pthread_mutex_lock(&mutex);
    
    printf("Thread %d is starting\n", thrd_num);
    for(count=0; count<REPEAT_NUM; count++)
    {
       
        printf("\tThread %d:job %d delay=%d\n", thrd_num,count);
    }
    printf("Thread %d finish\n", thrd_num);
    /*线程解锁*/
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
}


int main(void)
{
   pthread_t thread[THREAD_NUM];
   int no=0, res;
   void *thrd_ret;
   
   pthread_mutex_init(&mutex, NULL);
   
   for(no=0; no<THREAD_NUM; no++)
   {
       res=pthread_create(&thread[no], NULL, thrd_func, (void *)no);
      
   }
   
   printf("creatr threads success\nwaiting for threads to finish....\n");
   
   for(no=0; no<THREAD_NUM; no++)
   {
      res=pthread_join(thread[no], &thrd_ret);
     
   }
  pthread_mutex_destroy(&mutex); <span style="font-family:Calibri;">/*销毁线程*/</span>
   return 0;
}


Sem_init()

函数的作用:初始化信号

函数的头文件:#include <semaphore.h>

函数的原型:int sem_init(sem_t *sem, int pshare, unsigned int value)

函数的参数:

          Pshare0

          Sem:信号量指针

          Value:信号里初始化

函数的返回值:

          成功:返回0

          出错:返回 -1

 

信号量的PV操作:

函数的原型:

         Int sem_wait(sem_t *sem)------------P操作

         Int sem_trywait(sem_t *sem)

         Int sem_post(sem_t *sem)------------V操作

         Int sem_getvalue(sem_t *sem)

         Int sem_destroy(sem_t *sem)

函数的参数:

        Sem:信号里指针

示例代码:线程的PV操作

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <sys/ipc.h>
#include <semaphore.h>
#include <fcntl.h>


int buff;
sem_t mutex,full;
int fd;
void inputnumber(void *arg);
void countnumber(void *arg);

int main()
{
    pthread_t id1,id2;
    pthread_t mon_th_id;
    int ret;
    
    /*创建信号量*/
    ret=sem_init(&mutex,0,1);
    ret+=sem_init(&full,0,0);
    if(ret!=0)
    {
        perror("sem_init");
    }
    
    
    
    
    ret=pthread_create(&id1,NULL,(void *)inputnumber,NULL);
    if(ret!=0)
        perror("pthread cread1");
    ret=pthread_create(&id2,NULL,(void *)countnumber,NULL);
    if(ret!=0)
        perror("pthread cread2");
    
    pthread_join(id1,NULL);
    pthread_join(id2,NULL);
    exit(0);
}

void inputnumber(void *arg)
{
    while(1)
    {
        
        sem_wait(&mutex);//使用sem_wait(3RT)可以阻塞调用线程,直到sem所指示的信号计数大于零为止
        buff=0;
        scanf("%d",&buff);
        if(buff==0||buff>100||buff<0)
        {
             exit(-1);
        }
        printf("the input number is %d\n",buff);
        sem_post(&full);//线程解除阻塞        
    }
}


void countnumber(void *arg)
{
    while(1)
    {
        sem_wait(&full);//阻塞操作使用sem_wait(3RT)可以阻塞调用线程,直到sem所指示的信号计数大于零为止
        printf("the square is:%d\n",buff*buff);
        sem_post(&mutex);
    }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值