zoukankan      html  css  js  c++  java
  • 线程同步之信号量(sem_init,sem_post,sem_wait)

    信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区。

    不多做解释,要使用信号量同步,需要包含头文件semaphore.h。

    主要用到的函数:

    • int sem_init(sem_t *sem, int pshared, unsigned int value);,其中sem是要初始化的信号量,pshared表示此信号量是在进程间共享还是线程间共享,value是信号量的初始值。
    • 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操作。
     
     
    //用户从终端输入任意字符然后统计个数显示,输入end则结束
    //使用多线程实现:主线程获取用户输入并判断是否退出,子线程计数
    #include<stdio.h>
    #include <pthread.h>
    #include<stdlib.h>
    #include <string.h>
    #include <semaphore.h>


          
    char buf[100]={0}; 
    int flag;
    sem_t sem;
    // 子线程程序,作用是统计buf中的字符个数并打印
    void *func(void*arg)
    {
    // 子线程首先应该有个循环
    // 循环中阻塞在等待主线程激活的时候,子线程被激活后就去获取buf中的字符
    // 长度,然后打印;完成后再次被阻塞
    sem_wait(&sem);
    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;


    sem_init(&sem,0,0);

    ret=pthread_create(&th,NULL,func,NULL);
            if (ret != 0)
    {
    printf("pthread_create error.\n");
    return -1;
    }                    

    printf("输入一个字符串,以回车结束.\n");
    while(scanf("%s",buf))
    {
    // 去比较用户输入的是不是end,如果是则退出,如果不是则继续
    if(!strncmp(buf,"end",3))
    {
    printf("输入的字符串为:%s",buf);
    flag==1;
    sem_post(&sem);
    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;







    }
  • 相关阅读:
    flutter android 开发笔记(三.flutter和android数据交互)
    flutter android 开发笔记(二.module集成,混合页面)
    flutter android 开发笔记(一.集成)
    svn主干开辟分支、分支合并到主干
    svn主干开辟分支、分支合并到主干
    打包aar时把依赖的jar打包进aar中
    as修改已有项目的svn地址
    Flutter踩坑日记(一)
    android中两个不同名称的app不能同时安装
    aar、jar、so的引入和aar打包包含so、aar、jar文件
  • 原文地址:https://www.cnblogs.com/zhengAloha/p/8665719.html
Copyright © 2011-2022 走看看