线程同步之信号量

 

线程同步主要有信号量、互斥锁(互斥量)、条件变量三种方法来实现

首先要用到以下几个函数:

int sem_init(sem_t *sem, int pshared, unsigned int value);其中sem是要初始化的信号量,pshared表示此信号量是在进程间共享还是线程间共享(0表示线程间共享),value是信号量的初始值(一般也设为0)。
int sem_destroy(sem_t *sem);其中sem是要销毁的信号量。只有用sem_init初始化的信号量才能用sem_destroy销毁,二者成对出现。
int sem_wait(sem_t *sem);等待信号量(阻塞在当前函数,收到信号则返回,执行下一步),如果信号量的值大于0,将信号量的值减1,立即返回。如果信号量的值为0,则线程阻塞。相当于P操作。成功返回0,失败返回-1。
int sem_post(sem_t *sem); 释放信号量,让信号量的值加1。相当于V操作。

 

示例程序:

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


char buf[200] = {0};
sem_t sem;
unsigned int flag = 0;


// 子线程程序,作用是统计buf中的字符个数并打印
void *func(void *arg)
{
    // 子线程首先应该有个循环
    // 循环中阻塞在等待主线程激活的时候,子线程被激活后就去获取buf中的字符
    // 长度,然后打印;完成后再次被阻塞
    sem_wait(&sem);
    //while (strncmp(buf, "end", 3) != 0)
    while (flag == 0)
    {    
        printf("本次输入了%d个字符\n", strlen(buf));
        memset(buf, 0, sizeof(buf));
        sem_wait(&sem);
    }
    
    
    pthread_exit(NULL);
}


int main(void)
{
    int ret = -1;
    pthread_t th = -1;
    
    
    
    sem_init(&sem, 0, 0);
    
    ret = pthread_create(&th, NULL, func, NULL);
    if (ret != 0)
    {
        printf("pthread_create error.\n");
        exit(-1);
    }
    
    printf("输入一个字符串,以回车结束\n");
    while (scanf("%s", buf))
    {
        // 去比较用户输入的是不是end,如果是则退出,如果不是则继续        
        if (!strncmp(buf, "end", 3))
        {
            printf("程序结束\n");
            flag = 1;
            sem_post(&sem);    
            //exit(0);
            break;
        }
        
        // 主线程在收到用户收入的字符串,并且确认不是end后
        // 就去发信号激活子线程来计数。
        // 子线程被阻塞,主线程可以激活,这就是线程的同步问题。
        // 信号量就可以用来实现这个线程同步
        sem_post(&sem);    
    }

    
    // 回收子线程
    printf("等待回收子线程\n");
    ret = pthread_join(th, NULL);
    if (ret != 0)
    {
        printf("pthread_join error.\n");
        exit(-1);
    }
    printf("子线程回收成功\n");
    
    sem_destroy(&sem);
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值