線程同步與信號量學習(sem_t)


原文 from  https://www.cnblogs.com/zhengAloha/p/8665719.html

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

pthread_t ntid;

char buf[100] = {0};

int flag = 0;

sem_t sem;

void* func(void* arg)
{
    printf("please input the str first: \n");

    while(flag == 0)
    {
        memset(buf,0,sizeof(buf));
        sem_wait(&sem);    
        printf("please input the str.\n");        
    }
    pthread_exit(NULL);
}

int main()
{
    int err;
    sem_init(&sem,0,0);
    err = pthread_create(&ntid,NULL,func,NULL);
    if(err != 0)
    {
        printf("can not create thread : %s\n",strerror(err));
        return -1;
    }
    while(scanf("%s",buf))
    {
        printf("輸入的字符串為:%s \n",buf);
        if(!strncmp(buf,"end",3))
        {
            flag = 1;
            sem_post(&sem);
            break;
        }
        else
        {
            sem_post(&sem);
        }

    }
    printf("等待回收子線程\n");
    err = pthread_join(ntid, NULL);
    if (err != 0)
    {
    printf("pthread_join error.\n");
    exit(-1);
    }
    printf("子線程回收成功\n");

    sem_destroy(&sem);
    sleep(1);
    exit(0);
}

copy了一份代碼,稍微修改使其能顯示其同步性,mainThread 輸出之后,阻塞住的sub Thread 隨后輸出

2.另外關於等待超時返回的函數,sem_timedwait(sem_t*sem,const struct timespec*timeout),有時候我們不需要線程一直阻塞,需要一個超時機制,以下為5s超時后wait 返回示例。

void* func(void* arg)
{
    printf("please input the str first: \n");

    while(flag == 0)
    {
        memset(buf,0,sizeof(buf));
        wait(5000);    
        printf("please input the str.\n");        
    }
    pthread_exit(NULL);
}

int wait(int milliseconds)
{
    int ret = true;
    if(milliseconds > 0)
    {
        int s;
        struct timespec ts;
        if(clock_gettime(CLOCK_REALTIME,&ts)== -1)
        {
            ret = false;
        }
        ts.tv_sec += milliseconds/1000;

        ts.tv_nsec+= (milliseconds%1000)*1000000;

        if (ts.tv_nsec >= 1000000000)   //ns增加后超過1s則進位
            {
                ts.tv_nsec -= 1000000000;
                ts.tv_sec++;
            }

        while((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)  //當阻塞於某個慢系統調用的一個進程捕獲某個信號且相應信號處理函數返回時,該系統調用可能返回一個EINTR錯誤
        {
            continue;
        }
        if(s == -1)
        {
            if (errno == ETIMEDOUT)    //正常超時
                {
                    printf("process timeout \n");
                }
                else
                {
                    printf("process sem_timedwait error");
                }
                ret = false;
        }
    }
    else
    {
        ret= !sem_wait(&sem);
    }
    return ret;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM