Synchronization I

Semaphore

Named Semaphore:

    1. 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

    1. sem_wait:当semophore中的value大于等于1时,将value减1,然后继续进行;否则等待value可以减1
    1. sem_post:给value加1(两个线程同时加1不会起冲突)
    1. sem_close:关闭semaphore
    1. 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; 
} 

你可能感兴趣的:(Synchronization I)