使用两个线程访问全局字符串,一个线程不停反转字符串,另一个线程读字符串.
问题: 在反转字符串的过程中,可能另一个线程访问字符串,造成读取错误
解决方案:
使用全局变量控制两个线程执行顺序
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#define PRINT_ERR(msg) \
do { \
printf("%s:%s:%d\n", __FILE__, __func__, __LINE__); \
perror(msg); \
exit(-1); \
} while (0)
char buf[128] = "1234567";
int ready_read = 0;
void reverse(char *buf, int len) {
char *start = buf;
char *end = buf + len - 1;
while (start < end) {
char c = *start;
*start = *end;
*end = c;
start ++;
end --;
}
}
void *func2(void *arg) {
while (1) {
if (ready_read == 0) {
reverse(buf, strlen(buf));
ready_read = 1;
}
}
}
void *func1(void *arg) {
while (1) {
if (ready_read == 1) {
printf("%s\n", buf);
ready_read = 0;
}
}
}
int main(int argc, const char *argv[]) {
pthread_t tid1;
pthread_t tid2;
if (errno = pthread_create(&tid1, NULL, func1, NULL)) {
PRINT_ERR("error");
}
if (errno = pthread_create(&tid2, NULL, func2, NULL)) {
PRINT_ERR("error");
}
while (1) {
sleep(1);
}
return 0;
}
执行结果:
unbuntu@unbuntu:~ $ ./a.out
7654321
1234567
7654321
1234567
7654321
1234567
7654321
1234567
7654321
1234567
7654321
1234567
^C
加锁防止写过程中被读,或者读过程中被写
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#define PRINT_ERR(msg) \
do { \
printf("%s:%s:%d\n", __FILE__, __func__, __LINE__); \
perror(msg); \
exit(-1); \
} while (0)
pthread_mutex_t lock;
char buf[128] = "1234567";
void reverse(char *buf, int len) {
char *start = buf;
char *end = buf + len - 1;
while (start < end) {
char c = *start;
*start = *end;
*end = c;
start ++;
end --;
}
}
void *func2(void *arg) {
while (1) {
pthread_mutex_lock(&lock);
reverse(buf, strlen(buf));
pthread_mutex_unlock(&lock);
}
}
void *func1(void *arg) {
while (1) {
pthread_mutex_lock(&lock);
printf("%s\n", buf);
pthread_mutex_unlock(&lock);
}
}
int main(int argc, const char *argv[]) {
pthread_mutex_init(&lock, NULL);
pthread_t tid1;
pthread_t tid2;
if (errno = pthread_create(&tid1, NULL, func1, NULL)) {
PRINT_ERR("error");
}
if (errno = pthread_create(&tid2, NULL, func2, NULL)) {
PRINT_ERR("error");
}
while (1) {
sleep(1);
}
return 0;
}
执行结果: (此时线程不是顺序执行, 但读到的数据是正常的)
unbuntu@unbuntu:~ $ ./a.out
7654321
7654321
7654321
7654321
7654321
1234567
1234567
1234567
1234567
1234567
1234567
1234567
1234567
1234567
1234567
7654321
7654321
7654321
7654321
^C