互斥量是一个可以处于两态之一的变量:解锁和加锁。
为控制对关键代码的访问,必须在进入这段代码之前锁住一个互斥量,然后在完成操作之后解锁它。
代码:thread4.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
void *thread_function(void *arg);
pthread_mutex_t work_mutex; // 声明一个互斥量
#define WORK_SIZE 1024
char work_area[WORK_SIZE]; // 声明工作区
int time_to_exit = 0; // 变量time_to_exit
int main() {
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_mutex_init(&work_mutex, NULL); // 初始化互斥量
if (res != 0) {
perror("Mutex initialization failed");
exit(EXIT_FAILURE);
}
res = pthread_create(&a_thread, NULL, thread_function, NULL); // 启动新线程
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
// 主线程
// 首先给工作区加锁,读取文本到它里面,然后解锁以允许其他进程访问它并统计字符数目
// 我们周期性地对互斥量再加锁,检查字符数目是否已统计完,如果还需要等待,就释放互斥量,这种轮询的方式
pthread_mutex_lock(&work_mutex);
printf("Input some text. Enter 'end' to finish\n");
while (!time_to_exit) {
fgets(work_area, WORK_SIZE, stdin);
pthread_mutex_unlock(&work_mutex);
while (1) {
pthread_mutex_lock(&work_mutex);
if (work_area[0] != '\0') {
pthread_mutex_unlock(&work_mutex);
sleep(1);
} else {
break;
}
}
}
pthread_mutex_unlock(&work_mutex);
printf("\nWaiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined\n");
pthread_mutex_destroy(&work_mutex);
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg) {
sleep(1);
pthread_mutex_lock(&work_mutex); // 尝试对互斥量加锁,如果它已经被锁住,这个调用将被阻塞直到它被释放为止,
// 一旦获得访问权,我们就检查是否有申请退出程序的请求
// 如果不想退出,就统计字符个数,然后解锁互斥量并等待主线程继续运行
// 周期性的尝试给互斥量加锁,如果加锁成功,就检查是否主线程又有字符送来要处理
// 如果还没有,就解锁互斥量继续等待,如果有,就统计字符个数并再次进入循环
while (strncmp("end", work_area, 3) != 0) {
printf("You input %d characters\n", strlen(work_area) - 1);
work_area[0] = '\0';
pthread_mutex_unlock(&work_mutex);
sleep(1);
pthread_mutex_lock(&work_mutex);
while (work_area[0] == '\0') {
pthread_mutex_unlock(&work_mutex);
sleep(1);
pthread_mutex_lock(&work_mutex);
}
}
// 如果有退出程序的请求,就设置time_to_exit变量,再把工作区的第一个字符设置为'\0',然后退出
time_to_exit = 1;
work_area[0] = '\0';
pthread_mutex_unlock(&work_mutex);
pthread_exit(0);
}
编译(编译时需要加选项 -lphread):
gcc -g thread4.c -o thread4 -lpthread
运行:
./thread4
结果:
Input some text. Enter 'end' to finish
Whitasd
You input 7 characters
The Crod
You input 8 characters
pthread
You input 7 characters
hah end
You input 7 characters
edn
You input 3 characters
end
Waiting for thread to finish...
Thread joined