• Linux生产者和消费者模型 条件变量 信号量


    1. /*
    2. 条件变量类型 pthread_cond_t
    3. int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
    4. int pthread_cond_destory(pthread_cond_t * cond);
    5. int pthread_cond_wait(pthread_cond_t *restrict cond, const pthread_mutex_t *restrict mutex);
    6. 阻塞函数,调用了该函数,线程阻塞
    7. int pthread_cond_timewait(pthread_cond_t *restrict cond, const pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
    8. 等待多长时间,调用了该函数,线程阻塞直至时间结束
    9. int pthread_cond_signal(pthread_cond_t * cond);
    10. 唤醒至少一个等待的线程
    11. int pthread_cond_broadcast(pthread_cond_t * cond);
    12. 唤醒所有等待的线程
    13. */
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. pthread_mutex_t mutex;
    20. pthread_cond_t cond;
    21. struct Node
    22. {
    23. /* data */
    24. int num;
    25. struct Node *next;
    26. };
    27. struct Node * head = NULL;
    28. void * producer(void * arg) {
    29. while(1) {
    30. pthread_mutex_lock(&mutex);
    31. struct Node * newnode = (struct Node*) malloc(sizeof(struct Node));
    32. newnode->next = head;
    33. head = newnode;
    34. newnode->num = rand() % 1000;
    35. printf("add node, node num :%d, tid, %ld\n", newnode->num, pthread_self());
    36. pthread_cond_signal(&cond);
    37. pthread_mutex_unlock(&mutex);
    38. usleep(100);
    39. }
    40. return NULL;
    41. }
    42. void * customer(void * arg) {
    43. while(1) {
    44. pthread_mutex_lock(&mutex);
    45. struct Node *temp = head;
    46. if(head != NULL) {
    47. head = head->next;
    48. printf("delete node,num:%d, tid:%ld\n", temp->num, pthread_self());
    49. free(temp);
    50. pthread_mutex_unlock(&mutex);
    51. usleep(100);
    52. } else {
    53. pthread_cond_wait(&cond, &mutex);
    54. pthread_mutex_unlock(&mutex);
    55. }
    56. }
    57. return NULL;
    58. }
    59. int main() {
    60. pthread_mutex_init(&mutex, NULL);
    61. pthread_cond_init(&cond, NULL);
    62. pthread_t ptids[5], ctids[5];
    63. for(int i = 0; i < 5; i++) {
    64. pthread_create(&ptids[i], NULL, producer,NULL);
    65. pthread_create(&ctids[i], NULL, customer, NULL);
    66. }
    67. for(int i = 0; i < 5; i++) {
    68. pthread_detach(ptids[i]);
    69. pthread_detach(ctids[i]);
    70. }
    71. while(1) {
    72. sleep(10);
    73. }
    74. pthread_mutex_destroy(&mutex);
    75. pthread_cond_destroy(&cond);
    76. pthread_exit(NULL);
    77. return 0;
    78. }

    1. /*
    2. #include
    3. 函数量类型:sem_t
    4. int sem_init(sem_t *sem, int pshared, unsigned int value);
    5. 参数:
    6. -sem 需要初始化的信号量的地址
    7. -pshared 表示用在进程还是线程之间 0 线程 非0 进程
    8. -value:记录信号量中的值
    9. int sem_destory(sem_t *sem);
    10. 释放资源
    11. int sem_wait(sem_t *sem);
    12. 对信号量的值减一,如果值为零,就阻塞
    13. int sem_trywait(sem_t *sem);
    14. int sem_timewait(sem_t *sem, const struct timespec *abs_timeout);
    15. 等待多久的时间
    16. int sem_post(sem_t *sem);
    17. 信号量的值加一
    18. int sem_getvalue(sem_t *sem, int *sval);
    19. */
    20. #include
    21. #include
    22. #include
    23. #include
    24. #include
    25. #include
    26. pthread_mutex_t mutex;
    27. sem_t psem;
    28. sem_t csem;
    29. struct Node
    30. {
    31. /* data */
    32. int num;
    33. struct Node *next;
    34. };
    35. struct Node * head = NULL;
    36. void * producer(void * arg) {
    37. while(1) {
    38. sem_wait(&psem);
    39. pthread_mutex_lock(&mutex);
    40. struct Node * newnode = (struct Node*) malloc(sizeof(struct Node));
    41. newnode->next = head;
    42. head = newnode;
    43. newnode->num = rand() % 1000;
    44. printf("add node, node num :%d, tid, %ld\n", newnode->num, pthread_self());
    45. pthread_mutex_unlock(&mutex);
    46. sem_post(&csem);
    47. usleep(100);
    48. }
    49. return NULL;
    50. }
    51. void * customer(void * arg) {
    52. while(1) {
    53. sem_wait(&csem);
    54. pthread_mutex_lock(&mutex);
    55. struct Node *temp = head;
    56. head = head->next;
    57. printf("delete node,num:%d, tid:%ld\n", temp->num, pthread_self());
    58. free(temp);
    59. pthread_mutex_unlock(&mutex);
    60. sem_post(&psem);
    61. usleep(100);
    62. }
    63. return NULL;
    64. }
    65. int main() {
    66. pthread_mutex_init(&mutex, NULL);
    67. sem_init(&psem, 0, 8);
    68. sem_init(&csem, 0, 0);
    69. pthread_t ptids[5], ctids[5];
    70. for(int i = 0; i < 5; i++) {
    71. pthread_create(&ptids[i], NULL, producer,NULL);
    72. pthread_create(&ctids[i], NULL, customer, NULL);
    73. }
    74. for(int i = 0; i < 5; i++) {
    75. pthread_detach(ptids[i]);
    76. pthread_detach(ctids[i]);
    77. }
    78. while(1) {
    79. sleep(10);
    80. }
    81. pthread_mutex_destroy(&mutex);
    82. pthread_exit(NULL);
    83. return 0;
    84. }

    可以把sem理解为车位,wait就占一个车位,pos就空一个车位,车位被占满就阻塞,直至有多余的空出来的。

  • 相关阅读:
    Redis入门 看这一篇就够了
    Linux-用户管理
    java毕业设计在线课程教学大纲系统Mybatis+系统+数据库+调试部署
    @MultipartConfig注解
    美颜SDK是什么?美颜SDK和美颜APP有什么区别?
    集美大学 - 2840 - 实验3
    unittest测试框架的价值
    < 每日技巧: JavaScript代码优化 >
    【scala】类的属性
    C语言家政服务系统
  • 原文地址:https://blog.csdn.net/weixin_44273624/article/details/133279876