linux 线程互斥同步By信号量

24 篇文章 0 订阅
13 篇文章 0 订阅

今天有空就研究了下linux线程间的同步通信By信号量,离校钱只是匆匆的从网上看了一点概念性的东西(其实连概念也谈不上,就知道有信号量这么回事),对于具体的怎么用代码实现也不知道,现在正好有时间,研究了一下。

1、概念

1、信号量从本质上是一个非负整数计数器,是共享资源的数目,通常被用来控制对共享资源的访问。

2、信号量可以实现线程的同步和互斥

3、通过sem_post()和sem_wait()函数对信号量进行加减操作从而解决线程的同步和互斥。

4、信号量数据类型

sem_t

2、信号量创建和销毁

#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned value);
int sem_destroy(sem_t *sem);
返回: 成功返回0,出错返回错误编号
参数:
sem:
    信号量指针
pshared:
    是否在进程间共享的标志,0为不共享,1为共享。
value
    信号量的初始值

3、信号量的加和减操作

#include <semaphore.h>
int sem_post(sem_t *sem);
功能: 增加信号量的值
int sem_wait(sem_t *sem);
功能: 减少信号量的值
int sem_trywait(sem_t *sem);
功能: sem_wait()的非阻塞版本
返回: 成功返回0,出错返回错误编号

调用sem_post(): 一次信号量作加1操作
调用sem_wait():一次信号量作减1操作
当线程调用sem_wait()后,若信号量的值小于0则线程
阻塞。只有其它线程在调用sem_post()对信号量作加
操作后并且其值大于或等于0时,阻塞的线程才能继续运行。

5、例[利用线程信号量使三个线程交替循环输出10次]

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


#if 0
    int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);
int sem_wait(sem_t *sem);
    int sem_trywait(sem_t *sem);
    int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
int sem_post(sem_t *sem);
#endif

sem_t sem[3];
char ch = 'a';

void *th1(void *arg)
{
    int i = 0;
    while(i < 4)
    {
        sleep(2);
        i++;
        sem_wait(&sem[0]);
        printf("@(%d),%c\n",(int)pthread_self(),ch);
        ch = ch + 1;
        sem_post(&sem[1]);
    }
    return (void*)0;
}

void *th2(void *arg)
{

    int i = 0;
    while(i < 4)
    {
        sleep(2);
        i++;
        sem_wait(&sem[1]);
        printf("%c\n",ch);
        sem_post(&sem[2]);
    }
    return (void*)0;
}


void *th3(void *arg)
{
    sleep(2);
    int i = 0;
    while(i < 4)
    {
        i++;
        sem_wait(&sem[2]);
        printf("tangsong success!\n");
        sem_post(&sem[0]);
    }
    return (void*)0;
}
int main(void)
{
    pthread_t thread[3];
    int i = 0;
    sem_init(&sem[0],0,1);
    sem_init(&sem[1],0,0);
    sem_init(&sem[2],0,0);

    pthread_create(thread,NULL,th1,0);
    pthread_create(thread+1,NULL,th2,0);
    pthread_create(thread+2,NULL,th3,0);

    for(i = 0;i < 3;i++)
    {
        pthread_join(thread[i],0);
    }
    for(i = 0;i < 3;i++)
    {
        sem_destroy(&sem[i]);
    }
    return 0;
}

tsong@tslinux:~/summery/thread$ ./sem
@(1501783808),a
b
tangsong success!
@(1501783808),b
c
tangsong success!
@(1501783808),c
d
tangsong success!
@(1501783808),d
e
tangsong success!
执行结果如上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值