Semaphore
Named Semaphore:
-
- sem_open:新建有名信号(named)
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value)
name:semaphore名字
oflag:如O_CREAT,若不存在此semophore,新建此semophore
mode:权限,如0666,0777
value:semaphore初始值,有多少可用的resources
-
- sem_wait:当semophore中的value大于等于1时,将value减1,然后继续进行;否则等待value可以减1
-
- sem_post:给value加1(两个线程同时加1不会起冲突)
-
- sem_close:关闭semaphore
-
- sem_unlink:从系统中删除此有名信号量(named semaphore)
一个例子:(编译后加-lpthread)
/*semaphore.c*/
#include /* For O_* constants */
#include /* For mode constants */
#include
#include
int main(int argc, char * argv[]){
char * name = "my_semaphore";
int VALUE = 2;
sem_t * sema;
//If semaphore with name does not exist, then create it with VALUE
printf("Open or Create a named semaphore, %s, its value is %d\n", name,VALUE);
sema = sem_open(name, O_CREAT, 0666, VALUE);
//wait on semaphore sema and decrease it by 1
sem_wait(sema);
printf("Decrease semaphore by 1\n");
//add semaphore sema by 1
sem_post(sema);
printf("Add semaphore by 1\n");
//Before exit, you need to close semaphore and unlink it, when all processes have
//finished using the semaphore, it can be removed from the system using sem_unlink
sem_close(sema);
sem_unlink(name);
return 0;
}
Unnamed Semaphore
Unnamed Semaphore存在于memory,仅供同一process或不同process中memory map到同一semaphore的threads使用;named semaphore可供所有知道其名字的thread使用
#include
int sem_init(sem_t *sem, int pshared, unsigned int value);
pshared:表示semaphore是由process内thread共享,还是process间共享。若pshared为0,则由进程内共享,且应放在全局变量或heap上动态分配的变量,所有thread均可见的地址上。若非0,即process共享。
#include
int sem_destroy(sem_t *sem)
semaphore死掉了
Mutex
Mutes即value为1的semaphore
举个栗子:
gcc process-1.c -pthread -o process-1
gcc process-2.c -pthread -o process-2
./process-1 & ./process-2 &
/*process-1.c*/
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char * argv[]) {
sem_t * mutex;
char * c = "This is CSCI3150--An operating system course.\n";
// specify no buffering for stderr
setbuf(stderr, NULL);
mutex = sem_open("mutex_for_stderr", O_CREAT, 0666, 1);
sem_wait(mutex);
while (* c != '\0') {
fputc(* c, stderr);
c++;
sleep(1);
}
sem_post(mutex);
sem_close(mutex);
sem_unlink("mutex_for_stderr");
return 0;
}
/*process-2.c*/
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char * argv[]) {
sem_t * mutex;
char * c = "This is CSCI3150--An operating system course.\n";
// specify no buffering for stderr
setbuf(stderr, NULL);
mutex = sem_open("mutex_for_stderr", O_CREAT, 0666, 1);
sem_wait(mutex);
while (* c != '\0') {
fputc(* c, stderr);
c++;
sleep(rand()%2+1);
}
sem_post(mutex);
sem_close(mutex);
sem_unlink("mutex_for_stderr");
return 0;
}
两个例子
Producer and Customer Problem
作者:tzshlyt
来源:CSDN
原文:https://blog.csdn.net/tzshlyt/article/details/53150697?utm_source=copy
(October 12 2018)
#include
#include
#include
#include
#include
#define NUM 5
int queue[NUM];
sem_t blank_number, product_number;
void *producer(void *arg)
{
int p = 0;
while(1)
{
sem_wait(&blank_number);
queue[p] = rand() % 1000 + 1;
printf("produce %d\n", queue[p]);
p = (p + 1) % NUM;
sem_post(&product_number);
sleep(1);
//sleep(rand()%5);
}
}
void *consumer(void *arg)
{
int c = 0, i;
while(1)
{
sem_wait(&product_number);
for(i=0; i < NUM; i++)
{
printf("%d ", queue[i]);
}
putchar('\n');
printf("consume %d\n", queue[c]);
queue[c] = 0;
sem_post(&blank_number);
c = (c+1)%NUM;
sleep(3);
//sleep(rand()%5);
}
}
int main()
{
pthread_t pid, cid;
// 可用资源数为 NUM = 5
sem_init(&blank_number, 0, NUM);
sem_init(&product_number, 0, 0);
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
sem_destroy(&blank_number);
sem_destroy(&product_number);
return 0;
}
Conditon Variable实现semaphore,用pthread_cond_wait()实现sem_wait()等function
#include
#include
#include
#include
#define NUM 5
int queue[NUM];
int current_num;
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_cond_t blank_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void *producer(void *arg)
{
int p = 0, i;
while(1)
{
pthread_mutex_lock(&lock);
while(current_num >= NUM)
{
pthread_cond_wait(&blank_product, &lock);
}
queue[p] = rand() % 1000 + 1;
printf("produce %d\n", queue[p]);
p = (p + 1) % NUM;
current_num ++;
pthread_mutex_unlock(&lock);
printf("after produce --- current_num: %d\n", current_num);
for(i=0; i < NUM; i++)
{
printf("%d ", queue[i]);
}
putchar('\n'); sleep(1);
//sleep(rand()%5);
pthread_cond_signal(&has_product);
}
}
void *consumer(void *arg)
{
int c = 0, i;
while(1)
{
pthread_mutex_lock(&lock);
pthread_cond_wait(&has_product, &lock);
printf("consume %d\n", queue[c]);
queue[c] = 0; c = (c+1)%NUM;
current_num--;
printf("after consume --- current_num: %d\n", current_num);
for(i=0; i < NUM; i++)
{
printf("%d ", queue[i]);
}
putchar('\n');
pthread_mutex_unlock(&lock);
sleep(3);
//sleep(rand()%5);
pthread_cond_signal(&blank_product);
}
}
int main()
{
pthread_t pid, cid;
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
printf("----\n");
return 0;
}