C语言学习之进程同步、线程同步——信号量(semaphore)

(一)概念

  1. 信号量是一个整数,这个整数允许多进程或多线程同步他们的操作。这个整数必须大于等于0.

  2. linux库函数中,类似有名映射、匿名映射,有名管道、无名管道,信号量也有有名信号量和匿名信号量。匿名信号量在内存中,不在文件系统中,一般用于线程之间的同步;有名信号量需要创建文件,一般用于进程之间的同步。有名信号量见:有名信号量

(二)匿名信号量库函数

  1. #include
    int sem_init(sem_t *sem, int pshared, unsigned int value);
    功能:初始化一个匿名信号量
    参数:
    sem 指定了要初始化的信号量的地址
    pshared 0 多线程 非0 多进程
    value 指定了信号量的初始值
    返回值:
    成功 0
    错误 -1 errno被设置

  2. #include
    int sem_destroy(sem_t *sem);
    功能:销毁一个匿名信号量
    参数:
    sem 指定要销毁的匿名信号量的地址
    返回值:
    成功 0
    错误 -1 errno被设置

  3. #include
    int sem_post(sem_t *sem);
    功能:信号量的值加1操作.如果因此变为大于0.等待信号量的值变为大于0的进程或线程被唤醒,继续对信号量的值减一.
    参数:
    sem 指定具体的信号量
    返回值:
    成功 0
    错误 -1 errno被设置 信号量的值不变

  4. #include
    int sem_wait(sem_t *sem);
    功能:减一操作 如果当前信号的值大于0,继续立即返回.
    如果当前信号量的值等于0.阻塞,直到信号量的值变为大于0.
    参数:
    sem 指定具体的信号量
    返回值:
    成功 0
    错误 -1 errno被设置 信号量的值不变

  5. int sem_trywait(sem_t *sem);
    功能:尝试wait,不阻塞

  6. int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
    功能:带时间的wait

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    typedef int que_t[6];
    que_t q;
    sem_t p;//可生产的数量
    sem_t c;//可消费的数量
    
    //生产者线程
    void *p_func(void *arg){
    	int t = 0;
    	while(1){
    		sem_wait(&p);
    		q[t] = rand() % 1000 + 1;
    		printf("p:%d\n", q[t]);
    		t = (t + 1) % 6;
    		sem_post(&c);
    		sleep(rand()%4+1);
    	}
    	return NULL;
    }
    
    //消费者线程
    void *c_func(void *arg){
    	int h = 0;
    	int tmp;
    	while(1){
    		sem_wait(&c);
    		tmp = q[h];
    		q[h] = -1;
    		h = (h+1)%6;
    		sem_post(&p);
    		printf("c:%d\n", tmp);
    		sleep(rand()%4+1);
    	}
    	return 0;
    }
    
    int main(void){
    	//初始化信号量的值
    	sem_init(&p, 0, 6);
    	sem_init(&c, 0, 0);
    	srand(time(NULL));
    	//创建两个线程,一个用于生产者,一个用于消费者
    	pthread_t tid, cid;
    	pthread_create(&tid, NULL, p_func, NULL);
    	pthread_create(&cid, NULL, c_func, NULL);
    	//阻塞等待线程汇合
    	pthread_join(tid, NULL);
    	pthread_join(cid, NULL);
    	//销毁信号量
    	sem_destroy(&p);
    	sem_destroy(&c);
    	return 0;
    }
    

你可能感兴趣的:(C语言)