一个多线程售票示例:
// 三个窗口, 共100张票
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int tickets = 100; //所有线程都共享这100张票
void* sellticket(void* arg){
// 卖票
while(tickets>0){
usleep(6000); //间隔6000微秒
printf("%ld 正在卖第 %d 张门票\n", pthread_self(), tickets);
tickets--;
}
return NULL;
}
int main(){
//创建3个子线程
pthread_t tid1, tid2, tid3;
pthread_create(&tid1, NULL, sellticket, NULL);
pthread_create(&tid2, NULL, sellticket, NULL);
pthread_create(&tid3, NULL, sellticket, NULL);
//回收子线程资源, 阻塞
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
//或者设置线程分离
//pthread_detach(tid1);
//pthread_detach(tid2);
//pthread_detach(tid3);
pthread_exit(NULL); //退出主线程
return 0;
}
运行
140146921383680 正在卖第 100 张门票
140146921383680 正在卖第 99 张门票
...
140146921383680 正在卖第 94 张门票
140146921383680 正在卖第 93 张门票
140146921383680 正在卖第 92 张门票
140146921383680 正在卖第 91 张门票
140146921383680 正在卖第 90 张门票
140146921383680 正在卖第 89 张门票
140146929776384 正在卖第 90 张门票
140146929776384 正在卖第 87 张门票
140146929776384 正在卖第 86 张门票
...
出现问题: 三个线程会同时抢占共享资源导致数据出现错误, 所以我们要求在A线程操作共享数据时, B,C线程不允许操作
线程同步
- 线程的主要优势在于,能够通过全局变量来共享信息。不过,这种便捷的共享是有代价的:必须确保多个线程不会同时修改同一变量,或者某一线程不会读取正在由其他线程修改的变量。
- 临界区是指访问某一共享资源的代码片段,并且这段代码的执行应为原子操作,也就是同时访问同一共享资源的其他线程不应中断该片段的执行。
- 线程同步:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内存地址进行操作,而其他线程则处于等待状态。