本文出自http://www.wenbanana.com/?p=446稻草人博客,欢迎访问!
互斥
简单地理解就是,一个线程进入工作区后,如果有其他线程想要进入工作区,它就会进入等待状态,要等待工作区内的线程结束后才可以进入。
基本函数
(1) pthread_mutex_init函数
原型:int pthread_mutex_init ( pthread_mutex_t *mutex, const pthread_mutexattr_t* attr);
描述:设置互斥量的属性
参数:第一个参数:预先声明的pthread_mutex_t对象指针
第二个参数:互斥锁属性,NULL表示使用默认属性
返回值:成功时返回0, 失败时返回一个错误代码
(2) pthread_mutex_lock函数
原型:int pthread_mutex_lock ( pthread_mutex_t *mutex );
描述:pthread_mutex_lock返回时,互斥锁被锁定,如果这个互斥锁被一个线程锁定和拥有,那么另一个线程要调用这 个函数会进入堵塞状态(即等待状态),直到互斥锁被释放为止。
返回值:成功时返回0, 失败时返回一个错误代码
(3) pthread_mutex_unlock函数
原型:int pthread_mutex_unlock ( pthread_mutex_t *mutex );
描述:释放互斥锁
返回值:成功时返回0, 失败时返回一个错误代码
(4) pthread_mutex_destroy函数
原型:int pthread_mutex_destroy ( pthread_mutex_t *mutex );
描述:删除互斥锁
返回值:成功时返回0, 失败时返回一个错误代码
实例
lock.c文件
描述:这个程序主要可以概括为主线程负责接受输入的字符串,而子线程则负责统计并输出字符数。
#include <stdio.h> #include <unistd.h> #include <stdlib.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; int main() { int res; pthread_t a_thread; void *thread_result; /*初始化互斥量*/ res = pthread_mutex_init(&work_mutex, NULL); if (res != 0) { perror("互斥量初始化失败!"); exit(EXIT_FAILURE); } /*启动新线程*/ res = pthread_create(&a_thread, NULL, thread_function, NULL); if (res != 0) { perror("线程创建失败"); exit(EXIT_FAILURE); } pthread_mutex_lock(&work_mutex); printf("请输入一些文本内容. 输入“end”结束\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("\n等待线程结束...\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); } /*主线程首先锁定工作区,在获取输入的字符后,释放工作区,让其他线程对字符个数进行统计。work_area[0[为空字符时表示统计结束。通过周期性地对互斥量进行加锁,检查是否已经统计完。*/ /*在线程中要执行的代码*/ void *thread_function(void *arg) { sleep(1); pthread_mutex_lock(&work_mutex); while(strncmp("end", work_area, 3) != 0) { printf("你输入了 %d 个字符\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 = 1; work_area[0] = '\0'; pthread_mutex_unlock(&work_mutex); pthread_exit(0); }
/*在新线程一上来先试图对互斥量进行加锁。如果它已经被锁上,新线程就会进入堵塞状态知道互斥锁释放为止,
一旦可以进入工作区,就先检查是否有退出请求(end)如果有,就设置time_to_exit变量和work_area,然后退出程序。
如果没有退出,那么就对字符个数进行统计。把work_area[0]设置为空,表示统计工作完成。接下来就释放互斥锁,
等待主线程的运行,周期性地给互斥量加锁,如果加锁成功,就检查主线程是否又给我们新的字符串统计。如果没有,
就释放互斥锁继续等待,*/
编译执行:gcc -D_REENTRANT fork.c -o fork -lpthread
运行结果如下:
参考文献:Linux程序设计