sw_rwlock.c 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /************************************************************************
  2. * AUTHOR: NiuJiuRu
  3. * FILENAME: sw_rwlock.c
  4. * DESCRIPTION: 读写锁, 也称共享锁
  5. * NOTE: 主要用于多线程同步访问全局共享资源
  6. * HISTORY:
  7. * 1, [2014-01-24] created by NiuJiuRu
  8. * 2, [2026-03-17] 优化修改"sw_rwlock_rdlock()"和"sw_rwlock_wrlock()"函数,
  9. * 避免依赖系统时间, 导致的超时误差或跳变问题
  10. ***********************************************************************/
  11. #include "swapi.h"
  12. #include "swmem.h"
  13. #include "sw_rwlock.h"
  14. /* 创建读写锁 */
  15. void *sw_rwlock_create()
  16. {
  17. pthread_rwlock_t *rwlock = NULL;
  18. pthread_rwlockattr_t attr;
  19. rwlock = (pthread_rwlock_t *)sw_heap_malloc(sizeof(pthread_rwlock_t));
  20. if(rwlock)
  21. {
  22. if(pthread_rwlockattr_init(&attr) != 0) { sw_heap_free(rwlock); return NULL; }
  23. // note: "If the process-shared attribute is PTHREAD_PRO-CESS_PRIVATE, the read-write lock shall only be
  24. // operated upon by threads created within the same process as the thread that initialized the read-write lock;
  25. // if threads of differing processes attempt to operate on such a read-write lock, the behavior is undefined."
  26. if(pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE) != 0 || pthread_rwlock_init(rwlock, &attr) != 0) { sw_heap_free(rwlock); rwlock = NULL; }
  27. pthread_rwlockattr_destroy(&attr);
  28. }
  29. return rwlock;
  30. }
  31. /* 销毁读写锁 */
  32. void sw_rwlock_destroy(void *hRWLock)
  33. {
  34. pthread_rwlock_t *rwlock = (pthread_rwlock_t *)hRWLock;
  35. pthread_rwlock_destroy(rwlock);
  36. sw_heap_free(rwlock);
  37. }
  38. /* 读写锁上锁-读(超时设置的时间单位为: 毫秒, 并且当timeout = -1时表示无限等待) */
  39. int sw_rwlock_rdlock(void *hRWLock, int timeout)
  40. {
  41. pthread_rwlock_t *rwlock = (pthread_rwlock_t *)hRWLock;
  42. struct timespec start, now; int ret;
  43. if(timeout < 0)
  44. {
  45. return pthread_rwlock_rdlock(rwlock);
  46. }
  47. clock_gettime(CLOCK_MONOTONIC, &start);
  48. while((ret = pthread_rwlock_tryrdlock(rwlock)) == EBUSY)
  49. {
  50. clock_gettime(CLOCK_MONOTONIC, &now);
  51. long long elapsed = (now.tv_sec*1000LL + now.tv_nsec/1000000) - (start.tv_sec*1000LL + start.tv_nsec/1000000);
  52. if(elapsed >= timeout) { errno = ETIMEDOUT; return -1; }
  53. else delay_ms(1); // 释放CPU占用, 避免过载
  54. }
  55. return ret == 0 ? 0 : -1;
  56. }
  57. /* 读写锁上锁-写(超时设置的时间单位为: 毫秒, 并且当timeout = -1时表示无限等待) */
  58. int sw_rwlock_wrlock(void *hRWLock, int timeout)
  59. {
  60. pthread_rwlock_t *rwlock = (pthread_rwlock_t *)hRWLock;
  61. struct timespec start, now; int ret;
  62. if(timeout < 0)
  63. {
  64. return pthread_rwlock_wrlock(rwlock);
  65. }
  66. clock_gettime(CLOCK_MONOTONIC, &start);
  67. while((ret = pthread_rwlock_trywrlock(rwlock)) == EBUSY)
  68. {
  69. clock_gettime(CLOCK_MONOTONIC, &now);
  70. long long elapsed = (now.tv_sec*1000LL + now.tv_nsec/1000000) - (start.tv_sec*1000LL + start.tv_nsec/1000000);
  71. if(elapsed >= timeout) { errno = ETIMEDOUT; return -1; }
  72. else delay_ms(1); // 释放CPU占用, 避免过载
  73. }
  74. return ret == 0 ? 0 : -1;
  75. }
  76. /* 读写锁解锁 */
  77. void sw_rwlock_unlock(void *hRWLock)
  78. {
  79. pthread_rwlock_t *rwlock = (pthread_rwlock_t *)hRWLock;
  80. pthread_rwlock_unlock(rwlock);
  81. }