#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
// 系统分配线程 和代码顺序无关
sem_t can_add;
sem_t can_mul;
sem_t can_scanf;

int x,y;
/*
void Print()
{
    printf("************************\n");
    printf("can add is %ld\n",can_add.__align);
    printf("can mul is %ld\n",can_mul.__align);
    printf("can scanf is %ld\n",can_scanf.__align);
    printf("************************\n");
}
*/
void *thread_add(void *arg)
{
    while (1)
    {
//        Print();
        printf("add enter\n");
        sem_wait(&can_add); // 第一次到这边 因为初始signal 是 0 所以就阻塞在这句了 
                            // 第二次由while那边add 加了1个 signal , 此时add signal = 1,就可以执行这一句,执行后add signal= 0 后面代码继续执行
        printf("add\n");
        printf("%d+%d=%d\n",x,y,x+y);
        sem_post(&can_mul);
        printf("add end\n");
 //       Print();
    } 
}

void *thread_mul(void *arg)
{
    while (1)
    {
//        Print();
        printf("mul enter\n");
        sem_wait(&can_mul);// 第一次到这边 因为初始signal 是 0 所以就阻塞在这句了 
        printf("mul\n");
        printf("%d*%d=%d\n",x,y,x*y);
        sem_post(&can_scanf);
        printf("mul end\n");
 //       Print();
    }
    
}


// 这个程序总共1个进程 有三个线程 1个是主函数中 一个是add 一个是mul 总共这三个线程


int main()
{
    pthread_t tid;
 //   int arg[2];
 // 设置信号量 信号量 为 1 遇到 sem_wait 会变为 0 继续执行后面代码 而信号量 为 0 时 遇到 sem_wait 会阻塞
    sem_init(&can_scanf,0,1);
    sem_init(&can_add,0,0);
    sem_init(&can_mul,0,0);
//    Print();
    printf("thread begin create\n");
// 创造线程 此后三个线程是并发运行的 
    if(pthread_create(&tid,NULL,thread_add,NULL) < 0)
    {
        perror("Create thread_add failed!\n");
    }
    if(pthread_create(&tid,NULL,thread_mul,NULL))
    {
        perror("Create thread_mul failed!\n");
    }
    printf("thread end create\n");
    while (1)
    {
  //      Print();
        printf("while enter\n");
        // 第一次 can_scanf signal = 1 wait后值为0 代码可以继续向后执行 第二次循环 scanf signal = 0 发生阻塞 这时 add singal = 1 执行 add 线程
        sem_wait(&can_scanf);    // wait 第一次如果信号量是1的话 会往下执行一次 但是如果此时信号量是0的话 就开始阻塞 所以  就会执行 信号量为1的线程
        printf("Please input two integers:");
        scanf("%d%d",&x,&y);
        sem_post(&can_add);  // 给add 增加信号量为 1
        printf("the thread is %ld\n",syscall(SYS_gettid));
        printf("while end\n");
   //     Print();
    }
    
}

可以发现两次运行 while enter add enter mul enter 每次运行顺序是不一样的 这是因为一开始三个线程都是在运行状态 它们的运行顺序是由系统分配的 这就是为什么 需要用 wait 降低信号量来阻塞 这样就可以控制线程运行顺序

posted on 2022-01-11 16:11  Rabbit_XIN  阅读(31)  评论(0)    收藏  举报