C语言线程pthread操作

文章介绍了线程和进程的基本概念,强调了它们之间的区别,如进程的独立内存空间和线程的共享内存。接着详细阐述了在C语言中使用pthread库进行线程的创建、退出、等待、获取ID和比较等操作,以及线程互斥锁的应用,包括创建、销毁、加锁和解锁。此外,还讨论了线程条件变量的等待和触发,以及如何在实际应用中使用这些机制来控制线程执行的顺序和同步。
摘要由CSDN通过智能技术生成

目录

概念

线程与进程的区别

操作

线程创建、退出、等待、获取id、判断

线程创建:

线程退出

线程等待

线程获取id

线程比较

实际运用

线程的互斥锁应用

创建互斥锁

销毁互斥锁

加锁

解锁

实际运用

线程条件下等待和触发

线程等待

等待触发

创建条件

销毁条件

实际应用

线程的锁和cond的初始化宏


概念

线程与进程的区别

进程是程序执行的实例,进程是线程的容器,一个进程中的多个线程共用一个地址空间

进程之间拥有自己独立的内存空间,一个进程死掉后不会对其他进程产生影响,而线程只有自己的堆栈和局部变量的地址空间,一个线程死掉对于整个线程死掉。

进程间通讯不方便需要进行通道或者其他特定的通讯方式,而线程拥有共享内存,改变共享内存可以达到线程间通讯的效果

操作

操作部分有为三个大点:1.线程创建、退出、等待、获取id、判断

2.线程的互斥锁应用

3.线程条件下等待和触发

线程创建、退出、等待、获取id、判断

线程部分api都需要包括头文件include<pthread.h>

线程创建:

int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr, void*(*start_rtn)(void*),void*restrict arg);

第一个参数tidp需要我们传一个pthread_t类型的地址进去,然后该函数会将生成的线程id存放入里面。

第二个参数是线程属性,一般为NULL即可

第三个参数为线程运行函数的函数指针

第四个参数为传入创建线程的参数的地址,一个参数既取变量地址即可,多个参数可以将其变为结构体或字符串等再将其地址传入。

线程退出

int pthread_exit(void* rval_ptr);

变量rval_ptr是线程退出(结束)后传回的参数,在线程等待的api中接收转存

线程等待

int pthread_join(pthread_t thread,void **rval_ptr);

第一个参数为等待退出线程的id,是线程创建时的第一个参数。

第二个参数是接收线程退出时传回来的参数。

线程获取id

pthread_t pthread_self(void)

返回当前线程的id

线程比较

因为线程id在不同操作系统有不同的表现形式,所以不能当做一个配套整形来比较,所以特别编写了一个api来比较线程id

int pthread_equal(pthread_t tid1,pthread_t pid2);

实际运用

思路:首先在main函数中我们创建线程函数func1,并传入参数arg,然后等待线程结束

在线程中打印main中传进来的arg以及线程id,然后结束线程并回传参数ret。

#include <stdio.h>
#include <pthread.h>

void *func1(void *arg)
{
        static int ret = 10;

        printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
        printf("t1:param = %d\n",*((int*)arg));

        pthread_exit((void*)&ret);
}


int main(void)
{
        pthread_t t1;
        int param = 100;
        int *Thread;
        int ret;

        ret = pthread_create(&t1,NULL,func1,(void*)&param);

        pthread_join(t1,(void **)&Thread);

        printf("pr:%ld thread is create\n",(unsigned long)pthread_self());
        printf("pr:Thread = %d\n",*Thread);
        return 0;
}

线程的互斥锁应用

创建互斥锁

int pthread_mutex_inti(pthread_mutex_t *restrict mutex,const pthread_mutex_attr_t *restrict attr)

第一个参数是创建的互斥锁id的存放地址

第二个参数是互斥锁属性一般为NULL

销毁互斥锁

int pthread_mutex_destroy(pthread_mutex_t *mutex);

参数是要关闭的互斥锁id 

加锁

int pthread_mutex_lock(pthread_mutex_t *mutex);

参数是要关闭的互斥锁id  

解锁

int pthread_mutex_unlock(pthread_mutex_t *mutex);

参数是要关闭的互斥锁id  

实际运用

线程1和线程2交替增加全局变量,但要求全局变量增加为3的操作一定为线程1的操作,即可用互斥锁来实现

因为系统不能确定线程1线程2哪个先运行所以我们用互斥锁来规范运行次序,而且当线程二先运行时,我们运行一次就开关一次互斥锁,则线程1就可以达到我们需要的效果。

#include <stdio.h>
#include <pthread.h>

int p_data=0;
pthread_mutex_t mutex;

void *func1(void *arg)
{
        //加锁,相当于取钥匙开锁,如果其他线程未将钥匙放回来,则死等
        pthread_mutex_lock(&mutex);    

        while(1)
        {
                printf("t1:%d\n",p_data++);
                sleep(1);
                if(p_data == 3)
                {
                        printf("succes=========================================================//\n");

                        pthread_mutex_unlock(&mutex);    //开锁,相当于将钥匙放回来
                        pthread_exit(NULL);    //退出线程
                }
        }

}

void *func2(void *arg)
{
         //该线程中加一次全局变量开一次锁,所以不管第一次是线程1开锁还是线程2开锁,第三次一定的线程1累加到的,因为线程二加完一次就跳到线程1一直加到pdata=3.
        while(1)
        {
                pthread_mutex_lock(&mutex);
                printf("t2:%d\n",p_data++);
                sleep(1);
                pthread_mutex_unlock(&mutex);
        }


}

int main(void)
{
        pthread_t t1,t2;
        int param = 100;
        int *Thread;
        int ret;

        pthread_mutex_init(&mutex,NULL);

        ret = pthread_create(&t1,NULL,func1,(void*)&param);

        ret = pthread_create(&t2,NULL,func2,(void*)&param);
        while(1)
        {
                printf("main:%d\n",p_data);
                sleep(1);
                pthread_mutex_destroy(&mutex);
        }
        return 0;
}
       

线程条件下等待和触发

线程等待

int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t*restrict mutex);

第一个参数是pthread_cond_t类型的线程条件变量,第二个参数是线程的互斥锁id

等待触发

int pthread_cond_signal(&cond)

创建条件

pthread_cond_init(&cond,NULL);

销毁条件

pthread_cond_destroy(&cond);

实际应用

在线程2中加入条件则在条件成立时cond运行

而cond在线程1中等待条件成立

#include <stdio.h>
#include <pthread.h>

int p_data=0;
pthread_mutex_t mutex;
pthread_cond_t cond;

void *func1(void *arg)
{

        while(1)
        {
                pthread_cond_wait(&cond,&mutex);
                printf("t1:%d\n",p_data++);
                sleep(1);
                printf("succes=========================================================//\n");

//              pthread_exit(NULL);
                exit(0);
        }

}

void *func2(void *arg)
{

        while(1)
        {
                pthread_mutex_lock(&mutex);
                printf("t2:%d\n",p_data++);

                if(p_data == 3)
                {
                        pthread_cond_signal(&cond);
                }
                pthread_mutex_unlock(&mutex);
                sleep(1);
        }
}

int main(void)
{
        pthread_t t1,t2;
        int param = 100;
        int *Thread;
        int ret;

        pthread_mutex_init(&mutex,NULL);
        pthread_cond_init(&cond,NULL);

        ret = pthread_create(&t1,NULL,func1,(void*)&param);

        ret = pthread_create(&t2,NULL,func2,(void*)&param);
//              printf("main:%d\n",p_data);
        sleep(1);
        pthread_join(t2,NULL);
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
 }    

线程的锁和cond的初始化宏

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALQER;
pthread_cond_t cond = PTHREAD_COND_INITIALQER;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值