线程间同步实现--通过互斥锁和条件变量
来源:互联网 发布:手机视频录像软件 编辑:程序博客网 时间:2024/05/17 00:15
信号量是一种用于提供不同进程或一个给定进程的不同线程间同步手段。
在Posix中,已经有一套信号接口,用于同一个进程中不同线程同步,其接口为:
int sem_init(sem_t *sem, int pshared, unsigned int value);int sem_wait(sem_t *sem);int sem_trywait(sem_t *sem);int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);int sem_destroy(sem_t *sem);int sem_getvalue(sem_t *sem);
但Posix标准实现信号量的主要的目的是提供一种进程间同步的方式,注意重点是解决进程间,不过信号量也可以用于线程间同步。
进程间同步通过有名信号量(sem_open(), sem_close(), sem_unlink(), sem_wait(), sem_post(), sem_getvalue(), sem_trywait())
线程间同步一般通过互斥锁和条件变量来实现,但具体情况,还要看应用场景。
下面主要介绍通过互斥锁和条件变量实现信号实现,代码比较简单:
#ifndef __DL_SEMA_H__#define __DL_SEMA_H__#ifdef __cplusplus#if __cplusplusextern "C" {#endif#endiftypedef void* dl_sema_t;extern intdl_sema_create(dl_sema_t *pSema, unsigned int init_cnt);extern intdl_sema_destroy(dl_sema_t sema);extern intdl_sema_p(dl_sema_t sema, int timeout);extern intdl_sema_v(dl_sema_t sema);#ifdef __cplusplus#if __cplusplus}#endif#endif#endif /* __DL_SEMA_H__ */
#include <pthread.h>#include <stdlib.h>#include <sys/time.h> /* gettimeofday() */#include "dl_sema.h"#ifdef __cplusplus#if __cplusplusextern "C" {#endif#endif#define SEMA_MAGIC 0xF147258Fstruct sema_info{ unsigned int magic; int cnt; pthread_mutex_t mutex; pthread_cond_t cond;};/* abstime = millsec + the current time */void dl_gettime(struct timespec *abstime, int millsec){ long sec, nsec; struct timeval cur_time; gettimeofday(&cur_time, 0); nsec = cur_time.tv_usec * 1000; sec = cur_time.tv_sec; nsec += (millsec%1000)*1000000; abstime->tv_nsec = nsec % 1000000000; sec += millsec/1000; sec += nsec / 1000000000; abstime->tv_sec = sec;}/* create a semaphore with init_cnt */int dl_sema_create(dl_sema_t *pSema, unsigned int init_cnt){ struct sema_info *sema; if(!pSema) return -1; sema = malloc(sizeof(struct sema_info)); if(!sema) return -1; if(pthread_mutex_init(&(sema->mutex), 0) != 0){ free(sema); return -1; } if( pthread_cond_init(&(sema->cond), 0) != 0){ pthread_mutex_destroy(&(sema->mutex)); free(sema); return -1; } sema->cnt = init_cnt; sema->magic = SEMA_MAGIC; *pSema = sema; return 0;}int dl_sema_p(dl_sema_t sema, int timeout){ struct sema_info *psema = (struct sema_info*) sema; int ret = 0; if(!psema || (psema->magic != SEMA_MAGIC) ) return -1; pthread_mutex_lock(&(psema->mutex)); if(psema->cnt <= 0){ /* wait forever */ if(timeout == 0){ while(psema->cnt <= 0){ if((ret = pthread_cond_wait(&(psema->cond), &(psema->mutex))) != 0){ pthread_mutex_unlock(&(psema->mutex)); return ret; } } } else { struct timespec abs_time; dl_gettime(&abs_time, timeout); while(psema->cnt <= 0){ ret = pthread_cond_timedwait(&(psema->cond), &(psema->mutex), &abs_time); if(ret != 0){ pthread_mutex_unlock(&(psema->mutex)); return ret; } } } } psema->cnt--; pthread_mutex_unlock(&(psema->mutex)); return 0;}int dl_sema_v(dl_sema_t sema){ int ret = 0; struct sema_info* psema = (struct sema_info*)sema; if(!psema || (psema->magic != SEMA_MAGIC) ) return -1; pthread_mutex_lock(&(psema->mutex)); psema->cnt++; ret = pthread_cond_signal(&(psema->cond)); if(ret != 0){ psema->cnt--; /* roll back */ pthread_mutex_unlock(&(psema->mutex)); return ret; } pthread_mutex_unlock(&(psema->mutex)); return 0;}int dl_sema_destroy(dl_sema_t sema){ struct sema_info* psema = (struct sema_info*)sema; int ret = 0; if(!psema || (psema->magic != SEMA_MAGIC) ) return -1; psema->magic = 0; if((ret = pthread_mutex_destroy(&(psema->mutex))) != 0) return ret; if((ret = pthread_cond_destroy(&(psema->cond))) != 0) return ret; free(psema); return 0;}#ifdef __cplusplus#if __cplusplus}#endif#endif
//简单测试代码:#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include "dl_sema.h"void *thread_1(void *arg){ int ret; dl_sema_t sema = (dl_sema_t)arg; ret = dl_sema_p(sema, 3000);/* 3s timeout */ if(ret == 0)printf("the semaphore come up !\n"); dl_sema_destroy(sema); return 0;}void *thread_2(void *arg){ dl_sema_t sema = (dl_sema_t)arg; dl_sema_v(sema); printf("OK!!!!\n"); return 0;}int main(int argc, char**argv){ pthread_t thid; dl_sema_t sema; if(dl_sema_create(&sema, 0)) printf("dl_sema_init failed.\n"); pthread_create(&thid, 0, thread_1, sema); pthread_create(&thid, 0, thread_2, sema); sleep(5); return 0;}
- 线程间同步实现--通过互斥锁和条件变量
- 利用条件变量实现线程间同步
- 利用条件变量实现线程间同步
- 线程间同步--互斥锁、条件变量、信号量
- 线程间同步--互斥锁、条件变量、信号量
- 线程间同步,条件变量
- 线程同步之互斥锁、读写锁和条件变量
- Linux下线程同步问题中的互斥锁和条件变量
- 线程同步的方法—互斥锁、信号量和条件变量
- 线程同步之mutex和条件变量
- 线程同步—条件变量和信号量
- 线程同步-条件变量
- 线程同步条件变量
- 线程同步---条件变量
- 线程同步条件变量
- 线程同步-----条件变量
- 线程同步-条件变量
- 线程间同步,条件变量,互斥锁的使用
- Java类文件(.class文件)版本号与JDK的对应关系
- 杂记之break,continue,goto语句的使用
- 用Python实现一个简单的文件传输协议
- Apache Jakarta Commons 工具集简介
- ASP.NET导出Excel(利用NPOI和EPPlus库,无需安装Office)
- 线程间同步实现--通过互斥锁和条件变量
- 关于电动汽车无线充电的一些看法
- 因为基站问题,所以手机定位有利也有弊!
- android SQLite使用SQLiteOpenHelper类对数据库进行操作
- 不要被不重要的人和事过多打搅,因为成功的秘诀就是抓住目标不放,而不是把时间浪费在无谓的琐事上
- 面试题几道--C/C++
- U盘分区的方法
- win7下安装IIS7
- Excel修改创建注意点[C#]