这个文章会首先会介绍下竞争条件的定义并举例说明下竞争条件可能造成的问题,之后会说一下临界区的概念和临界区问题的解决。 最后会讨论下信号量。
同步问题(Synchronization)
*上回提到,当multi-tasks被拆成多个不同的进程/线程让他们已并行的方式(条件是多核)完成会大大的提升效率。 但是多个进程或者线程之间的同步运行并且让他们按照某种条件或顺序来完成某些任务是一个麻烦的问题。 同步问题在进程或线程同步当中都会发生, 之后每次写俩写的麻烦, 之后会统称进程同步。
1. 竞争条件(Race Condition)
1.1 定义
细致一点说, 假设我要求进程PA和PB一起改变一个共享变量的时候。PA在修改的过程中,他的timer(或者说是time quantum)时间到了必须要进行context switch并切换到了PB,但此刻PA的修改并没有完成, PB所使用的是修改前的变量.那么这种情况下将会发生错误.
1.2 举例
写个比较经典的小代码:
#include <stdio.h>
#include <pthread.h>
#include <ctype.h>
#include <stdlib.h>
int total_words ;
void *count_words(void *);
main(int ac, char *av[])
{
pthread_t t1, t2; /* two threads */
if ( ac != 3 ){
printf("usage: %s file1 file2\n", av[0]);
exit(1);
}
total_words = 0;
pthread_create(&t1, NULL, count_words, (void *) av[1]);
pthread_create(&t2, NULL, count_words, (void *) av[2]);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("total words: %d\n", total_words);
}
void *count_words(void *f)
{
char *filename = (char *) f;
FILE *fp;
int c, prevc = '\0';
if ( (fp = fopen(filename, "r" )) != NULL ){
while( ( c = getc(fp)) != EOF ){
if ( !isalnum(c) && isalnum(prevc) )
total_words++;
prevc = c;
}