系统编程函数之线程

来源:互联网 发布:阿里云系统的手机 编辑:程序博客网 时间:2024/05/21 00:00
1、创建线程:pthread_create 即创建一个并发执行的流程,从属与进程,不和进程分离,线程和进程间共享所有资源
NAME
       pthread_create - create a new thread
SYNOPSIS
       #include <pthread.h> 
       int pthread_create(pthread_t *thread,const pthread_attr_t *attr,     参数1:设置线程的标识
                         void *(*start_routine) (void *),void *arg);                    参数2:设置线程属性,比如优先级等 默认属性写NULL
       Compile and link with -pthread.                                                    参数3:设置线程要执行的函数
RETURN VALUE                                                                                    参数4:设置要传给线程的参数 若创建成功,则执行run函数
       On success, pthread_create() returns 0; on error, it returns an error number, and the contents of *thread are undefined.
2、等待线程结束:pthread_join
NAME
       pthread_join - join with a terminated thread
SYNOPSIS
       #include <pthread.h>
       int pthread_join(pthread_t thread, void **retval);   参数1:线程标识符  参数2:用户的定义的指针,用来存储被等待线程的返回值
RETURN VALUE                                                                                                                //接收线程返回值
       On success, pthread_join() returns 0; on error, it returns an error number.
使用:
void *run(void *arg)
{
    int num = (int)arg;
    while (1)
    {
        printf("this is thread run:%d\n", num);
        sleep(1);
    }   
}
int main(void)
{   
    pthread_t thr;
    int ret = -1;
    //ret = pthread_create(&thr, NULL, run, NULL);
    ret = pthread_create(&thr, NULL, run , (void *)888);
    if (0 != ret)
    {
        perror("pthread_create");
        return -1;
    }
    while (1)
    {
        printf("this is main while\n");
        sleep(1);
    }
    //等待指定线程的结束
    pthread_join(thr, NULL);
    return 0;
}
       代码中如果没有pthread_join主线程会很快结束,从而使整个进程结束,从而使创建的线程没有机会机会开始执行就结束了,加了pthread_join后,主线程会一直等待直到等待的进程结束自己才结束,使创建的线程有机会执行


4、进程锁:pthread_mutex_t
//线程锁  -->互斥量
pthread_mutex_t mutex;
//将多个语句合成一个原子操作
//原子操作不可分
//要么都执行
//要么都不执行
pthread_mutex_t proMutex;
pthread_mutex_lock(&proMutex);
pthread_mutex_unlock(&proMutex);




使用:
//信号量:用数字来表示资源的可用数量
//生产者和消费者问题
/*
 十个空盘子
 生产者往盘子中生产食物
     检查空盘子的数量,
     若大于0则表示有空盘子可供生产,
         生产了则空盘子量减一,有食物盘子量加一
     若等于0则表示没有空盘子,则阻塞等待
 消费者消费盘子中的食物
     检查有食物盘子的数量,若大于0则表示有食物消费
         消费了则有食物盘子量减一,空盘子量加一
     若等于0则表示没有有食物的盘子,则阻塞等待
 */
pthread_mutex_t proMutex;
pthread_mutex_t cusMutex;
#define DISH_NUM 10  //盘子的数量
#define CUS_NUM 15   //消费者的数量
#define PRO_NUM 5    //生产者的数量
sem_t emptysem; //空盘子信号量,表示空盘子资源数
sem_t fullsem; //有食物盘子信号量,表示有食物资源数
//数组表示盘子
char g_caDish[DISH_NUM];
//生产者线程要执行的函数
//表示生产者将要往第几个盘子中生产食物
int g_iProNum = 0;
void *product(void *arg)
{
    int num = (int)arg;
    while (1)
    {
        sem_wait(&emptysem);
        pthread_mutex_lock(&proMutex);
        srand((unsigned int)time(NULL));
        g_caDish[g_iProNum] = rand() % 26 + 'A';
        printf("第%d个生产者往第%d个盘子中生产了%c食物\n", num+1, g_iProNum+1, g_caDish[g_iProNum]);
        g_iProNum = (g_iProNum+1)%DISH_NUM;
        pthread_mutex_unlock(&proMutex);
        //将fullsem的值加一
        //通知所有阻塞等待fullsem的线程
        sem_post(&fullsem);
        sleep(1);
    }
}
//消费者线程要执行的函数
int g_iCusNum = 0;
void *custom(void *arg)
{
    int num = (int)arg;
    while (1)
    {
        sem_wait(&fullsem);
        pthread_mutex_lock(&cusMutex);
        printf("第%d个消费者消费了第%d个盘子中的%c食物\n", num+1, g_iCusNum+1, g_caDish[g_iCusNum]);
        g_caDish[g_iCusNum] = '\0';
        g_iCusNum = (g_iCusNum+1)%DISH_NUM;
        pthread_mutex_unlock(&cusMutex);
        sem_post(&emptysem);
        sleep(1);
    }
}
int main(void)
{   
    memset(g_caDish, '\0', DISH_NUM);
    sem_init(&emptysem, 0, 10);
    sem_init(&fullsem, 0, 0);
    pthread_t cus[CUS_NUM];
    int i = 0;
    //创建消费者线程
    for (; i < CUS_NUM; i++)
    {
        pthread_create(cus+i, NULL, custom
                       , (void*)i);
    }
    //创建生产者线程
    pthread_t pro[PRO_NUM];
    for (i = 0; i < PRO_NUM; i++)
    {
        pthread_create(pro+i, NULL, product
                       , (void *)i);
    }
    //等待线程结束
    for (i = 0; i < CUS_NUM; i++)
    {
        pthread_join(cus[i], NULL);
    }
    for (i = 0; i < PRO_NUM; i++)
    {
        pthread_join(pro[i], NULL);
    }
    return 0;
}


1,让线程结束pthread_cancel(thr); 屏蔽结束信号pthread_setcancelstate()
void *run(void *arg)
{
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE   , NULL);
    int i = 0;
    while (1)
    {
        printf("this is thread run\n");
        sleep(1);
        i++;
        if (5 == i)
        {
            pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
        }
    }
}

int main(void)
{   
    pthread_t thr;
    pthread_create(&thr, NULL, run, NULL);
    pthread_cancel(thr);
    pthread_join(thr, NULL);
    return 0;
}

2、pthread_exit 线程中调用exit结束整个线程
void pthread_exit(void *retval);
将需要的返回值类型传给void *retval

void getStrFromSTDIN(char caBuf[32])
{
    read(STDIN_FILENO, caBuf, 32);
    char *p = strrchr(caBuf, '\n');
    if (NULL != p)
    {
        *p = '\0';
    }
    else
    {
        while ('\n' != getchar())
        {}
    }
}
void *run(void *arg)
{
    char caBuf[32] = {'\0'};
    int i = 0;
    while (1)
    {
        getStrFromSTDIN(caBuf);
        if (0 == strcmp(caBuf, "exit"))
        {
            pthread_exit((void*)666);
        }
        i++;
        if (5 == i)
        {
            break;
        }
    }
    return (void *)888;
}
int main(void)
{   
    pthread_t thr;
    pthread_create(&thr, NULL, run, NULL);
    void *retval = NULL;
    pthread_join(thr, &retval);
    if ((void*)666 == retval)
    {
        printf("线程是输入exit结束的\n");
    }
    else if ((void *)888 == retval)
    {
        printf("线程是正常结束的\n");
    }
    return 0;
}