当前位置:   article > 正文

多线程访问全局变量(两个线程,一读一写)_两个线程访问同一个全局变量

两个线程访问同一个全局变量

使用两个线程访问全局字符串,一个线程不停反转字符串,另一个线程读字符串. 

问题: 在反转字符串的过程中,可能另一个线程访问字符串,造成读取错误

解决方案:

使用全局变量控制两个线程执行顺序

  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #define PRINT_ERR(msg) \
  8. do { \
  9. printf("%s:%s:%d\n", __FILE__, __func__, __LINE__); \
  10. perror(msg); \
  11. exit(-1); \
  12. } while (0)
  13. char buf[128] = "1234567";
  14. int ready_read = 0;
  15. void reverse(char *buf, int len) {
  16. char *start = buf;
  17. char *end = buf + len - 1;
  18. while (start < end) {
  19. char c = *start;
  20. *start = *end;
  21. *end = c;
  22. start ++;
  23. end --;
  24. }
  25. }
  26. void *func2(void *arg) {
  27. while (1) {
  28. if (ready_read == 0) {
  29. reverse(buf, strlen(buf));
  30. ready_read = 1;
  31. }
  32. }
  33. }
  34. void *func1(void *arg) {
  35. while (1) {
  36. if (ready_read == 1) {
  37. printf("%s\n", buf);
  38. ready_read = 0;
  39. }
  40. }
  41. }
  42. int main(int argc, const char *argv[]) {
  43. pthread_t tid1;
  44. pthread_t tid2;
  45. if (errno = pthread_create(&tid1, NULL, func1, NULL)) {
  46. PRINT_ERR("error");
  47. }
  48. if (errno = pthread_create(&tid2, NULL, func2, NULL)) {
  49. PRINT_ERR("error");
  50. }
  51. while (1) {
  52. sleep(1);
  53. }
  54. return 0;
  55. }

执行结果:

  1. unbuntu@unbuntu:~ $ ./a.out
  2. 7654321
  3. 1234567
  4. 7654321
  5. 1234567
  6. 7654321
  7. 1234567
  8. 7654321
  9. 1234567
  10. 7654321
  11. 1234567
  12. 7654321
  13. 1234567
  14. ^C

加锁防止写过程中被读,或者读过程中被写

  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #define PRINT_ERR(msg) \
  8. do { \
  9. printf("%s:%s:%d\n", __FILE__, __func__, __LINE__); \
  10. perror(msg); \
  11. exit(-1); \
  12. } while (0)
  13. pthread_mutex_t lock;
  14. char buf[128] = "1234567";
  15. void reverse(char *buf, int len) {
  16. char *start = buf;
  17. char *end = buf + len - 1;
  18. while (start < end) {
  19. char c = *start;
  20. *start = *end;
  21. *end = c;
  22. start ++;
  23. end --;
  24. }
  25. }
  26. void *func2(void *arg) {
  27. while (1) {
  28. pthread_mutex_lock(&lock);
  29. reverse(buf, strlen(buf));
  30. pthread_mutex_unlock(&lock);
  31. }
  32. }
  33. void *func1(void *arg) {
  34. while (1) {
  35. pthread_mutex_lock(&lock);
  36. printf("%s\n", buf);
  37. pthread_mutex_unlock(&lock);
  38. }
  39. }
  40. int main(int argc, const char *argv[]) {
  41. pthread_mutex_init(&lock, NULL);
  42. pthread_t tid1;
  43. pthread_t tid2;
  44. if (errno = pthread_create(&tid1, NULL, func1, NULL)) {
  45. PRINT_ERR("error");
  46. }
  47. if (errno = pthread_create(&tid2, NULL, func2, NULL)) {
  48. PRINT_ERR("error");
  49. }
  50. while (1) {
  51. sleep(1);
  52. }
  53. return 0;
  54. }

执行结果: (此时线程不是顺序执行, 但读到的数据是正常的)

  1. unbuntu@unbuntu:~ $ ./a.out
  2. 7654321
  3. 7654321
  4. 7654321
  5. 7654321
  6. 7654321
  7. 1234567
  8. 1234567
  9. 1234567
  10. 1234567
  11. 1234567
  12. 1234567
  13. 1234567
  14. 1234567
  15. 1234567
  16. 1234567
  17. 7654321
  18. 7654321
  19. 7654321
  20. 7654321
  21. ^C
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/240497
推荐阅读
相关标签
  

闽ICP备14008679号