赞
踩
头文件: <semaphore.h>
/***************************************************************************************** 函数:信号量创建 原型:int sem_init(sem_t* sem, int pshared, unsigned int value); 形参列表 sem :信号量 pshared :[FALSE] 表示信号量sem用于线程间通信,且sem应当处于多线程可以共同访问的空间, 比如全局变量、在堆上动态分配的变量。 [TRUE]表示信号量用于进程间通信,且sem应处于共享内存或多进程可以共同访问的空 间,由父进程以fork()创建的子进程,如果它们拥有共同的内存空间,那么父子进程都 可以访问sem(任何可以访问同一共享内存的的进程都可以操控信号量。 value :sem的值 返回值 [0]表示创建成功 [-1]表示表示错误,并设置errno指示错误情况 示例: sem_t semID; //全局变量 int ret = sem_init(&semID, 0, 2); ******************************************************************************************/
/*****************************************************************************************
函数:信号量等待
原型:①int sem_wait(sem_t* sem);
②int sem_trywait(sem_t* sem);
③int sem_timedwait(sem_t* sem, const struct timespec* abs_timeout);
形参列表
sem :信号量
abs_timeout :等待时间,sem_wait()是阻塞等待,sem_trywait()是非阻塞等待,
sem_timedwait()是定时等待。
返回值
所有这些函数在成功时返回0;在错误时,信号量的值保持不变,返回-1,且errno被设置以指示错误
******************************************************************************************/
/*****************************************************************************************
函数:发射(发送、抛出、释放)信号量
原型:int sem_post(sem_t* sem);
描述:Sem_post增加sem(unlocks)所指向的信号量。 如果信号量的值因此大于0,那么在sem_wait()调用中
阻塞的另一个进程或线程将被唤醒,并继续锁定信号量。
返回值
成功返回0,失败返回-1,且信号量的值保持不变,且errno被设置以指示错误
******************************************************************************************/
编译:添加 -lpthread 选项
示例:gcc -lpthread code.c -o a.out
/* 示例代码:创建两个线程访问同一个全局变量number */ #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <semaphore.h> #include <pthread.h> #include <sys/types.h> unsigned int number = 0; void* thread1(void* para); //线程1服务函数 void* thread2(void* para); //线程2服务函数 int main(int argc, char** argv) { pthread_t threadID1, threadID2; int ret = 0; ret = pthread_create(&threadID1, NULL, thread1, NULL); //创建线程1 if(ret) { printf("Thread1 create failed!\n"); exit(EXIT_FAILURE); } ret = pthread_create(&threadID2, NULL, thread2, NULL); //创建线程2 if(ret) { printf("Thread2 create failed!\n"); exit(EXIT_FAILURE); } pthread_join(threadID1, NULL); //等待线程thread1结束 pthread_join(threadID2, NULL); //等待线程thread2结束 ptherad_exit((void*)0); //退出现场main return 0; } void* thread1(void* para) { printf("Function thread1 running...\n"); while(1) { number = 100; sleep(1); printf("number: %u\n", number); } pthread_exit((void*)0); } void* thread2(void* para) { unsigned int count = 0; printf("Function thread2 running...\n"); while(1) { count++; number = count; } pthread_exit((void*)0); }
结果分析:没有二元信号量的约束,线程thread1对number的赋值几乎不会等于100,原因是线程thread2对number的访问导致的。
/* 示例代码:创建两个线程访问同一个全局变量number,并加以信号量限制 */ #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <semaphore.h> #include <pthread.h> #include <sys/types.h> unsigned int number = 0; sem_t semID; void* thread1(void* para); void* thread2(void* para); int main(int argc, char** argv) { pthread_t threadID1, threadID2; int ret = 0; ret = pthread_create(&threadID1, NULL, thread1, NULL); if(ret) { printf("Thread1 create failed!\n"); exit(EXIT_FAILURE); } ret = pthread_create(&threadID2, NULL, thread2, NULL); if(ret) { printf("Thread2 create failed!\n"); exit(EXIT_FAILURE); } ret = sem_init(&semID, 0, 1); if(ret == -1) { printf("Sem create failed!\n"); exit(EXIT_FAILURE); } pthread_join(threadID1, NULL); pthread_join(threadID2, NULL); ptherad_exit((void*)0); return 0; } void* thread1(void* para) { printf("Function thread1 running...\n"); while(1) { sem_wait(&semID); //等待信号量 number = 100; sleep(1); printf("number: %u\n", number); sem_post(&semID); //释放信号量 } pthread_exit((void*)0); } void* thread2(void* para) { unsigned int count = 0; printf("Function thread2 running...\n"); while(1) { sem_wait(&semID); count++; number = count; sem_post(&semID); } pthread_exit((void*)0); }
结果分析:加入信号量后,不管是线程thread1还是线程thread2对number的访问都不能同时进行,对全局变量number进行了很好的保护。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。