千家信息网

Linux中怎么创建两个线程来实现对一个数递加

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇"Linux中怎么创建两个线程来实现对一个数递加"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一
千家信息网最后更新 2025年11月07日Linux中怎么创建两个线程来实现对一个数递加

这篇"Linux中怎么创建两个线程来实现对一个数递加"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"Linux中怎么创建两个线程来实现对一个数递加"文章吧。

代码:

/*thread_example.c : c multiple thread programming in linux *author : falcon *e-mail : tunzhj03@st.lzu.edu.cn */#include #include #include #include #define max 10pthread_t thread[2];pthread_mutex_t mut;int number=0, i;void *thread1(){    printf ("thread1 : i'm thread 1/n");    for (i = 0; i < max; i++)    {        printf("thread1 : number = %d/n",number);        pthread_mutex_lock(&mut);            number++;        pthread_mutex_unlock(&mut);        sleep(2);    }    printf("thread1 :主函数在等我完成任务吗?/n");    pthread_exit(null);}void *thread2(){    printf("thread2 : i'm thread 2/n");    for (i = 0; i < max; i++)    {        printf("thread2 : number = %d/n",number);        pthread_mutex_lock(&mut);            number++;        pthread_mutex_unlock(&mut);        sleep(3);    }    printf("thread2 :主函数在等我完成任务吗?/n");    pthread_exit(null);}void thread_create(void){    int temp;    memset(&thread, 0, sizeof(thread));     //comment1    /*创建线程*/    if((temp = pthread_create(&thread[0], null, thread1, null)) != 0) //comment2           printf("线程1创建失败!/n");    else        printf("线程1被创建/n");    if((temp = pthread_create(&thread[1], null, thread2, null)) != 0) //comment3        printf("线程2创建失败");    else        printf("线程2被创建/n");}void thread_wait(void){    /*等待线程结束*/    if(thread[0] !=0)      {       //comment4          pthread_join(thread[0],null);        printf("线程1已经结束/n");     }    if(thread[1] !=0)      {         //comment5        pthread_join(thread[1],null);        printf("线程2已经结束/n");     }}int main(){    /*用默认属性初始化互斥锁*/    pthread_mutex_init(&mut,null);    printf("我是主函数哦,我正在创建线程,呵呵/n");    thread_create();    printf("我是主函数哦,我正在等待线程完成任务阿,呵呵/n");    thread_wait();    return 0;}

下面我们先来编译、执行一下

引文:

falcon@falcon:~/program/c/code/ftp$ gcc -lpthread -o thread_example thread_example.cfalcon@falcon:~/program/c/code/ftp$ ./thread_example我是主函数哦,我正在创建线程,呵呵线程1被创建线程2被创建我是主函数哦,我正在等待线程完成任务阿,呵呵thread1 : i'm thread 1thread1 : number = 0thread2 : i'm thread 2thread2 : number = 1thread1 : number = 2thread2 : number = 3thread1 : number = 4thread2 : number = 5thread1 : number = 6thread1 : number = 7thread2 : number = 8thread1 : number = 9thread2 : number = 10thread1 :主函数在等我完成任务吗?线程1已经结束thread2 :主函数在等我完成任务吗?线程2已经结束

引文:

线程相关操作

一 pthread_t

pthread_t在头文件/usr/include/bits/pthreadtypes.h中定义:
  typedef unsigned long int pthread_t;
  它是一个线程的标识符。

二 pthread_create

函数pthread_create用来创建一个线程,它的原型为:
  extern int pthread_create __p ((pthread_t *__thread, __const pthread_attr_t *__attr,
  void *(*__start_routine) (void *), void *__arg));
  第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。这里,我们的函数thread不需要参数,所以最后一个参数设为空指针。第二个参数我们也设为空指针,这样将生成默认属性的线程。对线程属性的设定和修改我们将在下一节阐述。当创建线程成功时,函数返回0,若不为0则说明创建线程失败,常见的错误返回代码为eagain和einval。前者表示系统限制创建新的线程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非法。创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。

三 pthread_join pthread_exit
  
函数pthread_join用来等待一个线程的结束。函数原型为:
  extern int pthread_join __p ((pthread_t __th, void **__thread_return));
  第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现。它的函数原型为:
  extern void pthread_exit __p ((void *__retval)) __attribute__ ((__noreturn__));
  唯一的参数是函数的返回代码,只要pthread_join中的第二个参数thread_return不是null,这个值将被传递给 thread_return。最后要说明的是,一个线程不能被多个线程等待,否则第一个接收到信号的线程成功返回,其余调用pthread_join的线程则返回错误代码esrch。
  在这一节里,我们编写了一个最简单的线程,并掌握了最常用的三个函数pthread_create,pthread_join和pthread_exit。下面,我们来了解线程的一些常用属性以及如何设置这些属性。

互斥锁相关

互斥锁用来保证一段时间内只有一个线程在执行一段代码。

一 pthread_mutex_init

函数pthread_mutex_init用来生成一个互斥锁。null参数表明使用默认属性。如果需要声明特定属性的互斥锁,须调用函数 pthread_mutexattr_init。函数pthread_mutexattr_setpshared和函数 pthread_mutexattr_settype用来设置互斥锁属性。前一个函数设置属性pshared,它有两个取值, pthread_process_private和pthread_process_shared。前者用来不同进程中的线程同步,后者用于同步本进程的不同线程。在上面的例子中,我们使用的是默认属性pthread_process_ private。后者用来设置互斥锁类型,可选的类型有pthread_mutex_normal、pthread_mutex_errorcheck、 pthread_mutex_recursive和pthread _mutex_default。它们分别定义了不同的上所、解锁机制,一般情况下,选用最后一个默认属性。

二 pthread_mutex_lock pthread_mutex_unlock pthread_delay_np

   pthread_mutex_lock声明开始用互斥锁上锁,此后的代码直至调用pthread_mutex_unlock为止,均被上锁,即同一时间只能被一个线程调用执行。当一个线程执行到pthread_mutex_lock处时,如果该锁此时被另一个线程使用,那此线程被阻塞,即程序将等待到另一个线程释放此互斥锁。

注意:

1 需要说明的是,上面的两处sleep不光是为了演示的需要,也是为了让线程睡眠一段时间,让线程释放互斥锁,等待另一个线程使用此锁。下面的参考资料1里头说明了该问题。但是在linux下好像没有pthread_delay_np那个函数(我试了一下,提示没有定义该函数的引用),所以我用了sleep来代替,不过参考资料2中给出另一种方法,好像是通过pthread_cond_timedwait来代替,里头给出了一种实现的办法。

2 请千万要注意里头的注释comment1-5,那是我花了几个小时才找出的问题所在。
如果没有comment1和comment4,comment5,将导致在pthread_join的时候出现段错误,另外,上面的comment2和comment3是根源所在,所以千万要记得写全代码。因为上面的线程可能没有创建成功,导致下面不可能等到那个线程结束,而在用pthread_join的时候出现段错误(访问了未知的内存区)。另外,在使用memset的时候,需要包含string.h头文件。

以上就是关于"Linux中怎么创建两个线程来实现对一个数递加"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

线程 函数 参数 属性 代码 任务 面的 内容 两个 成功 指针 正在 错误 运行 个数 不同 原型 时候 时间 标识 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全审查办法适用行业 远程服务器工程项目管理合同 数据库网站的搭建 北京浴客互联网科技有限公司 中国有声资源数据库方言调查 php数据库修改通过id 在日本做软件开发辛苦 快速的mysql数据库优化 软件开发一定要连接外网嘛 nas私人存储服务器制作 黄岛区管理系统软件开发公司 成都软件开发培训费用多少 软件开发公司会计怎么做 最牛的软件开发 网络安全宣传周问答题 服务器搭建网站收集数据 第八届国家网络安全周官网 数据库记录当前时间 湖南pdu服务器电源价格表 数据库无法锁定单元格 时尚网络技术培训 搭建本地sql数据库 西藏民族大学网络安全背景简介 县委组织部网络安全自查总结 计算机网络技术的两个方向 柳州软件开发有限公司招聘 网络安全密钥怎么用 访问银行服务器有两个ip出口 小学生宣誓网络安全公约 南开大学网络安全学院专业
0