首页 > 代码库 > Linux信号量实践(2)

Linux信号量实践(2)

信号量API综合实践

//实践1:封装PV原语
union mySemUn
{
    int              val;    // Value for SETVAL//
    struct semid_ds *buf;    // Buffer for IPC_STAT, IPC_SET//
    unsigned short  *array;  // Array for GETALL, SETALL//
    struct seminfo  *__buf;  // Buffer for IPC_INFO (Linux-specific)//
};

//封装V操作
int sem_V(int semid)
{
    struct sembuf buf = {0,+1,0};
    return semop(semid,&buf,1);
}
//封装P操作
int sem_P(int semid)
{
    struct sembuf buf = {0,-1,0};;
    return semop(semid,&buf,1);
}

int main()
{
    //创建或获取信号量
    int semid = semget(0x12345670,1,0666|IPC_CREAT);
    if (semid == -1)
    {
        err_exit("semget error");
    }

    //设置信号量的值
    int valueForSetSem = 0;
    cout << "Please input the value to set sem: ";
    cin >> valueForSetSem;

    union mySemUn setValue;
    setValue.val = valueForSetSem;
    //设置信号量
    if (semctl(semid,0,SETVAL,setValue) != 0)
    {
        err_exit("semctl SETVAL error");
    }

    //进入临界区
    sem_P(semid);
    cout << "Hello Xiaofang!" << endl;
    //退出临界区
    sem_V(semid);

    return 0;
}

//实践2:线程与信号量综合实践
union mySemUn
{
    int              val;    // Value for SETVAL//
    struct semid_ds *buf;    // Buffer for IPC_STAT, IPC_SET//
    unsigned short  *array;  // Array for GETALL, SETALL//
    struct seminfo  *__buf;  // Buffer for IPC_INFO (Linux-specific)//
};

//封装V操作
int sem_V(int semid)
{
    struct sembuf buf = {0,+1,0};
    return semop(semid,&buf,1);
}
//封装P操作
int sem_P(int semid)
{
    struct sembuf buf = {0,-1,0};;
    return semop(semid,&buf,1);
}

unsigned long long int count = 0;
void *threadForAddCount(void *arg)
{
    int semid = *static_cast<int *>(arg);
    for (;;)
    {
        sem_P(semid);
        ++ count;
        sem_V(semid);
    }
    pthread_exit(NULL);
}

void *threadForPrintCount(void *arg)
{
    for (;;)
    {
        cout << "count = " << count << endl;
        sleep(1);
    }
    pthread_exit(NULL);
}

int main()
{
    //创建或获取信号量
    int semid = semget(0x12345670,1,0666|IPC_CREAT);
    if (semid == -1)
    {
        err_exit("semget error");
    }

    //设置信号量的值
    int valueForSetSem = 0;
    cout << "Please input the value to set sem: ";
    cin >> valueForSetSem;

    union mySemUn setValue;
    setValue.val = valueForSetSem;
    //设置信号量
    if (semctl(semid,0,SETVAL,setValue) != 0)
    {
        err_exit("semctl SETVAL error");
    }

    pthread_t addThread[2];
    pthread_t printThread;
    //创建线程
    for (int i = 0; i < 2; ++i)
    {
        pthread_create(&addThread[i],NULL,threadForAddCount,&semid);
    }
    pthread_create(&printThread,NULL,threadForPrintCount,NULL);

    //等待线程终止
    for (int i = 0; i < 2; ++i)
    {
        pthread_join(addThread[i],NULL);
    }
    pthread_join(printThread,NULL);

    return 0;
}

void err_exit(std::string str)
{
    perror(str.c_str());
    exit(EXIT_FAILURE);
}

-Makefile

CC = g++ 
CPPFLAGS = -Wall -g -pthread

BIN = main
SOURCES = $(BIN.=.cpp)

.PHONY: clean all 

all: $(BIN)

$(BIN): $(SOURCES)

clean:
    -rm -rf $(BIN) bin/ obj/ core


Linux信号量实践(2)