sem_wait函数也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,这信号量的值将减到1。如果对一个值为0的信号量调用sem_wait(),这个函数就 会地等待直到有其它线程增加了这个值使它不再是0为止。如果有两个线程都在sem_wait()中等待同一个信号量变成非零值,那么当它被第三个线程增加 一个“1”时,等待线程中只有一个能够对信号量做减法并继续执行,另一个还将处于等待状态。
sem_post函数的作用是给信号量的值加上一个“1”,它是一个“原子操作”---即同时对同一个信号量做加“1”操作的两个线程是不会冲突的;而同 时对同一个文件进行读、加和写操作的两个程序就有可能会引起冲突。信号量的值永远会正确地加一个“2”--因为有两个线程试图改变它。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h> int myglobal; sem_t sem; void * thread_function(void *arg) { int i,j; for (i = 0; i < 10; i += 1) { sem_wait(&sem); j = myglobal; j = j+1; printf("."); fflush(stdout); sleep(1); myglobal = j; sem_post(&sem); } return NULL; } int main(void) { pthread_t mythread; int i; sem_init(&sem, 0, 1);//信号量初始化 if(pthread_create(&mythread, NULL, thread_function, NULL)) { printf("create thread error!\n"); abort(); } /* sleep(1);*/ for(i = 0; i < 10; i++) { sem_wait(&sem);//=0 myglobal = myglobal + 1; printf("o"); fflush(stdout); sleep(1); sem_post(&sem);//=1 } if(pthread_join(mythread, NULL)) { printf("waiting thread failed!\n"); abort(); } printf("myglobal equals %d\n",myglobal); exit(0); }
例子2:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <pthread.h> #include <semaphore.h> void * thread_function(void * arg); sem_t bin_sem; #define WORK_SIZE 1024 char work_area[WORK_SIZE]; int main(int argc, char const *argv[]) { int res; pthread_t pthread; void * thread_result; res = sem_init(&bin_sem,0,0);//step 1 if (res != 0) { perror("sem_init failed!"); exit(EXIT_FAILURE); } res = pthread_create(&pthread,NULL,thread_function,NULL);//step 2 if (res != 0) { perror("pthread_create failed!"); exit(EXIT_FAILURE); } printf("input some text. Enter end to finish\n"); while(strncmp("end",work_area,3) != 0) { fgets(work_area,WORK_SIZE,stdin); sem_post(&bin_sem);//step 3 } printf("the final work_area is : %s\n",work_area);//the result is end that reflect every time work_area overload res = pthread_join(pthread,&thread_result); if (res != 0) { perror("pthread_join failed!"); exit(EXIT_FAILURE); } sem_destroy(&bin_sem); exit(EXIT_SUCCESS); } void *thread_function(void * arg) { sem_wait(&bin_sem);//if sem value equals 0,and wait,else run while(strncmp("end",work_area,3) != 0) { printf("you input %d characters\n",strlen(work_area)-1);//remove the enter key sem_wait(&bin_sem);//if sem value equals 0,and wait,else run } pthread_exit(NULL); }