Linux 信号量 与 线程编程

来源:互联网 发布:c语言分割字符串 编辑:程序博客网 时间:2024/06/08 21:36


#include <stdio.h>
#include <fcntl.h>           /* For O_CREAT constants */
#include <semaphore.h>       /* For sem_ constants */
#include <pthread.h>         /* For pthread_create constants */


void pthreadRun(void *arg);
void pthreadStop(void *arg);


sem_t* semStop;
sem_t* semRun;


int main()
{
    pthread_t pID1, pID2;
    int nRetP1, nRetP2;


    printf("\n\n");


    // 创建信号量
    semStop = sem_open("semStop", /*O_RDWR |*/ O_CREAT, 0644, 0);  //
    semRun = sem_open("semRun,", /*O_RDWR |*/ O_CREAT, 0644,0);    //


    if(SEM_FAILED == semStop || SEM_FAILED == semRun) 
    {
        printf("Opened error\n");
        return 1;
    }
  
    // 初始化信号量
    sem_init(semStop, 0, 0); 
    // int sem_init(sem_t *sem, int pshared, unsigned int value);
    // If pshared has the value 0, then the semaphore is  shared  between  the threads  of  a  process
    // The value argument specifies the initial value for  the  semaphore.


    sem_init(semRun, 0, 0);


    // 创建 信号量同步的 线程
    printf("now create two threads for synchronization. \n");
    nRetP2 = pthread_create(&pID2, NULL, (void*) pthreadStop, NULL);
    usleep(2*1000);
    nRetP1 = pthread_create(&pID1, NULL, (void*) pthreadRun, NULL);


    if(nRetP1 != 0) {
          printf("nRetP1 pthread_create failed! \n");
          return 2;
    }


    if(nRetP2 != 0) {
          printf("nRetP2 pthread_create failed! \n");
          return 2;
    }


    // 关闭信号量
    sem_close(semStop);
    sem_close(semRun);


    // 暂停 60 秒, 观看两线程同步
    usleep(60*1000);
    printf("\n\n");


    return 0;
}




void pthreadRun(void *arg)
{
    while(1)
    { 
        // 等待开车
        printf("wait for semRun\n");
        sem_wait(semRun);
        
        // 正常行车
        printf("runing\n");


        // 停车
        printf("post semStop\n");
        sem_post(semStop);
    }
}


void pthreadStop(void *arg)
{
    while(1)
    {
        // 上乘客
        printf("get on the bus.\n");


        // 关车门,通知司机开车
        printf("post semRun.\n");
        sem_post(semRun);


        // 卖车票
        printf("Selling tickets.\n");


        // 等待停车
        printf("wait for semStop\n");
        sem_wait(semStop);


        // 下乘客
        printf("get off\n");


    }
}


/* 编译:(gcc 编译选项需要加入一个多线程选项: -pthread)
hangken@ubuntu:~$ gcc -o bus/bus -g bus/bus.c -pthread
*/


/* 运行结果:
hangken@ubuntu:~$ sudo ./bus/bus




now create two threads for synchronization. 
get on the bus.
post semRun.
Selling tickets.
wait for semStop
wait for semRun
runing
post semStop
Segmentation fault
hangken@ubuntu:~$ 


*/


/*  主要用到的信号量函数有:


    sem_init:初始化信号量sem_t,初始化的时候可以指定信号量的初始值,以及是否可以在多进程间共享。


    sem_wait:一直阻塞等待直到信号量>0。


    sem_timedwait:阻塞等待若干时间直到信号量>0。 //等待信号量变成>0,
    // int sem_wait_i( sem_t *psem, int mswait ) mswait为等待时间,若mswait<0则无穷等待,否则等待若干mswait毫秒


    sem_post:使信号量加1。


    sem_destroy:释放信号量。和sem_init对应。


    关于各函数的具体参数请用man查看。如man sem_init可查看该函数的帮助。
*/