linux 信号量

如同进程一样,线程也可以通过信号量来实现通信,虽然是轻量级的。
   线程使用的基本信号量函数有四个:

  #include <semaphore.h>

     1. 初始化信号量
      int sem_init (sem_t *sem , int pshared, unsigned int value);

      参数:
      sem - 指定要初始化的信号量;
      pshared - 信号量 sem 的共享选项,linux只支持0,表示它是当前进程的局部信号量;
      value - 信号量 sem 的初始值。

      2. 信号量值加1
      给参数sem指定的信号量值加1。
     int sem_post(sem_t *sem);

     3. 信号量值减1
      给参数sem指定的信号量值减1。
     int sem_wait(sem_t *sem);
      如果sem所指的信号量的数值为0,函数将会等待直到有其它线程使它不再是0为止。

     4. 销毁信号量
    销毁指定的信号量。
  int sem_destroy(sem_t *sem);
 

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
 
#define return_if_fail(p) if((p) == 0){printf ("[%s]:func error!\n", __func__);return;}
 
typedef struct _PrivInfo
{
    sem_t s1;
    sem_t s2;
    time_t end_time;
}PrivInfo;
 
static void info_init (PrivInfo* prifo);
static void info_destroy (PrivInfo* prifo);
static void* pthread_func_1 (PrivInfo* prifo);
static void* pthread_func_2 (PrivInfo* prifo);
 
int main (int argc, char** argv)
{
    pthread_t pt_1 = 0;
    pthread_t pt_2 = 0;
    int ret = 0;
    PrivInfo* prifo = NULL;
    prifo = (PrivInfo* )malloc (sizeof (PrivInfo));
 
    if (prifo == NULL)
    {
        printf ("[%s]: Failed to malloc priv.\n");
        return -1;
    }
 
    info_init (prifo);
    ret = pthread_create (&pt_1, NULL, (void*)pthread_func_1, prifo);
    if (ret != 0)
    {
        perror ("pthread_1_create:");
    }
 
    ret = pthread_create (&pt_2, NULL, (void*)pthread_func_2, prifo);
    if (ret != 0)
    {
        perror ("pthread_2_create:");
    }
 
    pthread_join (pt_1, NULL);
    pthread_join (pt_2, NULL);
    info_destroy (prifo);
    return 0;
}
 
static void info_init (PrivInfo* prifo)
{
    return_if_fail (prifo != NULL);
    prifo->end_time = time(NULL) + 10;
    sem_init (&prifo->s1, 0, 1);
    sem_init (&prifo->s2, 0, 0);
    return;
}
 
static void info_destroy (PrivInfo* prifo)
{
    return_if_fail (prifo != NULL);
    sem_destroy (&prifo->s1);
    sem_destroy (&prifo->s2);
    free (prifo);
    prifo = NULL;
    return;
}
 
static void* pthread_func_1 (PrivInfo* prifo)
{
    return_if_fail (prifo != NULL);
    while (time(NULL) < prifo->end_time)
    {
        sem_wait (&prifo->s2);
        printf ("pthread1: pthread1 get the lock.\n");
        sem_post (&prifo->s1);
        printf ("pthread1: pthread1 unlock\n");
        sleep (1);
    }
    return;
}
 
static void* pthread_func_2 (PrivInfo* prifo)
{
    return_if_fail (prifo != NULL);
    while (time (NULL) < prifo->end_time)
    {
        sem_wait (&prifo->s1);
        printf ("pthread2: pthread2 get the unlock.\n");
        sem_post (&prifo->s2);
        printf ("pthread2: pthread2 unlock.\n");
        sleep (1);
    }
    return;
}

1、互斥锁和信号量比较

    a、互斥锁功能上基本与二元信号量一样,但是互斥锁占用空间比信号量小,运行效率比信号量高。所以,如果要用于线程间的互斥,优先选择互斥锁。

 2、互斥锁和自旋锁比较

    a、互斥锁在无法得到资源时,内核线程会进入睡眠阻塞状态,而自旋锁处于忙等待状态。因此,如果资源被占用的时间较长,使用互斥锁较好,因为可让CPU调度去做其它进程的工作。

    b、如果被保护资源需要睡眠的话,那么只能使用互斥锁或者信号量,不能使用自旋锁。而互斥锁的效率又比信号量高,所以这时候最佳选择是互斥锁。

    c、中断里面不能使用互斥锁,因为互斥锁在获取不到锁的情况下会进入睡眠,而中断是不能睡眠的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值