精华内容
下载资源
问答
  • linux多线程编程实例
    2020-02-28 15:01:23

    Linux c多线程编程的4个实例
      在主流的操作系统中,多任务一般都提供了进程和线程两种实现方式,进程享有独立的进程空间,而线程相对于进程来说是一种更加轻量级的多任务并行,多线程之间一般都是共享所在进程的内存空间的。

    Linux也不例外,虽然从内核的角度来看,线程体现为一种对进程的"克隆"(clone),共享进程的资源。但是在用户空间提供了线程管理机制来实现对线程的管理,目前Linux中最流行的线程机制为LinuxThreads,下面以一个多线程编程实例来介绍该线程库的编程接口:

    示例1:线程的创建和退出,等待线程结束和获取线程的返回值

    #include

    #include

    #include

    /************************************************************

    *线程函数:线程运行执行的函数

    *参数p:通用类型的指针,启动线程时传递给线程函数的参数

    *返回值:通用类型指针,线程结束后启动线程的函数可以获取该值

    *************************************************************/

    void* task(void* p){

    double r = (double)p;

    printf("%lf\n",3.14rr);

    }

    void* task2(void* p){

    static int sum = 0;

    int i;

    for(i=1;i<11;i++)

    sum = sum+i;

    return ∑

    //pthread_exit(&sum);线程退出,和return等价

    }

    int main(){

    pthread_t id1,id2;

    double d = 1.0;

    int* pi = NULL;

    /*

    *创建线程函数,在主线程中调用该函数可以创建线程

    *参数1:线程ID,ID由系统分配,该参数是一个传出参数,类型为pthread_t *

    *参数2:线程属性,使用默认属性给0即可,类型为pthread_attr_t *

    *参数3:线程函数,即线程运行时代码,类型为void ()(void *)

    *参数4:传递给线程函数的参数

    */

    pthread_create(&id1,0,task,&d);//计算圆的面积

    pthread_create(&id2,0,task2,0);//计算累加和

    /*

    *等待线程结束函数,用于在一个线程中等待另外一个线程结束

    *参数1:要等待结束的线程的ID

    *参数2:结束线程的返回值的地址(由于是传出参数,所以是返回值的地址)

    */

    pthread_join(id1,0);

    pthread_join(id2,(void**)&pi);//pi=∑

    printf(“sum=%d\n”,*pi);

    return 0;

    }

    此外,我们还可以设置线程的属性,下面介绍设置线程分离属性的代码

    示例2:设置线程的分离属性

    #include

    #include

    //线程函数

    void* task(void* p){

    int i;

    for(i=0;i<50;i++){

    printf("%d\n",i);

    usleep(100000);//0.1秒

    }

    }

    int main(){

    pthread_t id;

    pthread_create(&id,0,task,0);

    /*

    *将线程设置为分离属性,分离属性的线程一旦结束,直接回收资源

    *因此当线程设置为分离属性后将无法再等待线程结束和获取线程的返回值

    *参数:设置分离属性的线程ID

    */

    pthread_detach(id);//detach的线程join

    //pthread_join(id,0);//无效

    int i;

    for(i=0;i<50;i++){

    printf(“main:%d\n”,i);

    usleep(100000);//0.1秒

    }

    }

    由于多线程之间是共享进程资源的,所以多线程编程时需要对共享资源的访问进行保护

    包括互斥和同步,常用的方式包括互斥锁和信号量

    示例3:互斥锁的使用

    #include

    #include

    char* data[5];//定义一个长度是5字符串数组

    int size = 0;//定义了当前下标,也是人数

    pthread_mutex_t lock;//1 声明

    void* task(void* p){

    pthread_mutex_lock(&lock);//3 加锁

    data[size] = (char*)p; //4 访问共享资源

    usleep(10000); ++size;

    pthread_mutex_unlock(&lock);//5 解锁

    }

    int main(){

    data[size] = “liubei”; size++;

    pthread_mutex_init(&lock,0);//2 初始化

    pthread_t id1,id2;

    pthread_create(&id1,0,task,“zhangfei”);

    pthread_create(&id2,0,task,“guanyu”);

    pthread_join(id1,0);

    pthread_join(id2,0);

    pthread_mutex_destroy(&lock);//6 删除

    int i;

    for(i=0;i

    printf("%s\n",data[i]);

    }

    示例4:信号量的使用

    #include

    #include

    #include

    #include

    sem_t sem; //1 分配

    void* task(void* p){

    int i = (int)p;

    printf(“第%d个线程申请连接\n”,i);

    sem_wait(&sem);//3 P操作(计数-1)

    printf(“第%d个线程申请成功\n”,i);

    srand(time(0));//4 模拟访问共享资源

    sleep(rand()%10);

    printf(“第%d个线程释放资源\n”,i);

    sem_post(&sem);//5 V操作(计数+1)

    }

    int main(){

    sem_init(&sem,0,10);//2 初始化

    int i;

    for(i=1;i<16;i++){

    pthread_t id;

    pthread_create(&id,0,task,(void*)i);

    }

    while(1);

    }

    更多相关内容
  • 主要介绍了Linux下的多线程编程实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 主要介绍了linux下的CC++多进程多线程编程实例详解的相关资料,需要的朋友可以参考下
  • Linux操作系统编程,主要提供高级编程技术及实践方面内容。主要侧重多线程互斥与同步控制程序设计、调试等。部分代码练习。
  • 线程如何去创建 ,多线程如何控制输出!互斥控制!
  • Linux多线程详解及简单实例 1.概念 进程:运行中的程序。 线程:一个程序中的多个执行路径。更准确的定义是:线程是一个进程内部的一个控制序列。 2.为什么要有线程? 用fork调用进程代价太高,需要让一个...
  • 直接看代码吧,代码里有注释 代码如下:#include <stdio>#include <stdlib>#include <string>#include <pthread>#include <time>#define MAX 3 int number =0;pthread_t id[2];pthread_mutex_t mut;...
  • Linux多线程编程实例解析

    万次阅读 多人点赞 2015-12-14 18:00:22
    Linux系统下的多线程遵循POSIX线程接口,称为 pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。顺便说一下,Linux 下pthread的实现是通过系统调用clone()来实现的。...

    Linux系统下的多线程遵循POSIX线程接口,称为 pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。顺便说一下,Linux 下pthread的实现是通过系统调用clone()来实现的。clone()是 Linux所特有的系统调用,它的使用方式类似fork,关于clone()的详细情况,有兴趣的读者可以去查看有关文档说明。下面我们展示一个最简单的 多线程程序 pthread_create.c。


    一个重要的线程创建函数原型:
    #include <pthread.h>
    int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr, void *(*start_rtn)(void),void *restrict arg);

    返回值:若是成功建立线程返回0,否则返回错误的编号
    形式参数:
                    pthread_t *restrict tidp 要创建的线程的线程id指针
                    const pthread_attr_t *restrict attr 创建线程时的线程属性
                    void* (start_rtn)(void) 返回值是void类型的指针函数
                    void *restrict arg   start_rtn的行参
                    
    例程1:                               
        功能:创建一个简单的线程
        程序名称:pthread_create.c   

    代码如下:

    #include <stdio.h>
    #include <pthread.h>
    
    void *mythread1(void)
    {
    	int i;
    	for(i = 0; i < 10; i++)
    	{
    		printf("This is the 1st pthread,created by xiaoqiang!\n");
    		sleep(1);
    	}
    }
    
    void *mythread2(void)
    {
    	int i;
    	for(i = 0; i < 10; i++)
    	{
    		printf("This is the 2st pthread,created by xiaoqiang!\n");
    		sleep(1);
    	}
    }
    
    int main(int argc, const char *argv[])
    {
    	int i = 0;
    	int ret = 0;
    	pthread_t id1,id2;
    
    	ret = pthread_create(&id1, NULL, (void *)mythread1,NULL);
    	if(ret)
    	{
    		printf("Create pthread error!\n");
    		return 1;
    	}
    
    	ret = pthread_create(&id2, NULL, (void *)mythread2,NULL);
    	if(ret)
    	{
    		printf("Create pthread error!\n");
    		return 1;
    	}
    	
    	pthread_join(id1,NULL);
    	pthread_join(id2,NULL);
    
    	return 0;
    }

    执行结果如下:

    fs@ubuntu:~/qiang/thread$ vi thread1.c
    fs@ubuntu:~/qiang/thread$ gcc -o thread1 thread1.c -lpthread
    fs@ubuntu:~/qiang/thread$ ./thread1
    This is the 2st pthread,created by xiaoqiang!
    This is the 1st pthread,created by xiaoqiang!
    This is the 2st pthread,created by xiaoqiang!
    This is the 1st pthread,created by xiaoqiang!
    This is the 2st pthread,created by xiaoqiang!
    This is the 1st pthread,created by xiaoqiang!
    This is the 2st pthread,created by xiaoqiang!
    This is the 1st pthread,created by xiaoqiang!
    This is the 2st pthread,created by xiaoqiang!
    This is the 1st pthread,created by xiaoqiang!
    This is the 2st pthread,created by xiaoqiang!
    This is the 1st pthread,created by xiaoqiang!
    This is the 1st pthread,created by xiaoqiang!
    This is the 2st pthread,created by xiaoqiang!
    This is the 2st pthread,created by xiaoqiang!
    This is the 1st pthread,created by xiaoqiang!
    This is the 1st pthread,created by xiaoqiang!
    This is the 2st pthread,created by xiaoqiang!
    This is the 2st pthread,created by xiaoqiang!
    This is the 1st pthread,created by xiaoqiang!
    fs@ubuntu:~/qiang/thread$ 
    

    两个线程交替执行。
    另外,因为pthread的库不是linux系统的库,所以在进行编译的时候要加上-lpthread,否则编译不过,会出现下面错误
    thread_test.c: 在函数 ‘create’ 中:
    thread_test.c:7: 警告: 在有返回值的函数中,程序流程到达函数尾
    /tmp/ccOBJmuD.o: In function `main':thread_test.c:(.text+0x4f):对‘pthread_create’未定义的引用
    collect2: ld 返回 1
    此例子介绍了创建线程的方法

     

    下面例子介绍向线程传递参数。
    例程2:
    功能:向新的线程传递整形值
    程序名称:pthread_int.c

    代码如下:

    #include <stdio.h>
    #include <pthread.h>
    
    void *create(void *arg)
    {
    	int *num;
    	num = (int *)arg;
    	printf("Create parameter is %d\n",*num);
    	return (void *)0;
    }
    
    int main(int argc, const char *argv[])
    {
    	pthread_t id1;
    	int error;
    
    	int test = 4;
    	int *attr = &test;
    
    	error = pthread_create(&id1,NULL,create,(void *)attr);
    
    	if(error)
    	{
    		printf("Pthread_create is not created!\n");
    		return -1;
    	}
    	sleep(1);
    
    	printf("Pthread_create is created..\n");
    	return 0;
    }

    执行结果如下:

    fs@ubuntu:~/qiang/thread$ vi thread2.c
    fs@ubuntu:~/qiang/thread$ gcc -o thread2 thread2.c -lpthread
    fs@ubuntu:~/qiang/thread$ ./thread2
    Create parameter is 4
    Pthread_create is created..
    fs@ubuntu:~/qiang/thread$ 
    

    例程总结:
        可以看出来,我们在main函数中传递的整行指针,传递到我们新建的线程函数中。

    在上面的例子可以看出来我们向新的线程传入了另一个线程的int数据,线程之间还可以传递字符串或是更复杂的数据结构。
    例程3:
    程序功能:向新建的线程传递字符串
    程序名称:pthread_string.c
    代码如下:

    #include <stdio.h>
    #include <pthread.h>
    
    void *create(char *arg)
    {
    	char *str;
    	str = arg;
    	printf("The parameter passed from main is %s\n",str);
    
    	return (void *)0;
    }
    
    int main()
    {
    	int error;
    	pthread_t id1;
    	char *str1 = "Hello ,xiaoqiang!";
    	char *attr = str1;
    	error = pthread_create(&id1, NULL, create, (void *)attr);
    
    	if(error != 0)
    	{
    		printf("This pthread is not created!\n");
    		return -1;
    	}
    	sleep(1);
    
    	printf("pthread is created..\n");
    	return 0;
    }

    执行结果如下:

    fs@ubuntu:~/qiang/thread$ ./thread3
    The parameter passed from main is Hello ,xiaoqiang!
    pthread is created..
    fs@ubuntu:~/qiang/thread$ 
    

    例程总结:
    可以看出来main函数中的字符串传入了新建的线程中。

    例程4:
    程序功能:向新建的线程传递字符串
    程序名称:pthread_struct.c

    代码如下:

    #include <stdio.h>
    #include <pthread.h>
    #include <stdlib.h>
    
    struct menber
    {
    	int a;
    	char *s;
    };
    
    void *create(void *arg)
    {
    	struct menber *temp;
    	temp = (struct menber *)arg;
    	printf("menber->a = %d\n",temp->a);
    	printf("menber->s = %s\n",temp->s);
    
    	return (void *)0;
    }
    
    int main()
    {
    	int error;
    	pthread_t id1;
    	struct menber *p;
    	p = (struct menber *)malloc(sizeof(struct menber));
    	p->a = 1;
    	p->s = "xiaoqiang!";
    
    	error = pthread_create(&id1,NULL,create,(void *)p);
    
    	if(error)
    	{
    		printf("pthread is not created!\n");
    		return -1;
    	}
    	sleep(1);
    	printf("pthread is created!\n");
    
    	free(p);
    	p = NULL;
    	return 0;
    }

    执行结果如下:

    fs@ubuntu:~/qiang/thread$ vi thread4.c
    fs@ubuntu:~/qiang/thread$ gcc -o thread4 thread4.c -lpthread
    fs@ubuntu:~/qiang/thread$ ./thread4
    menber->a = 1
    menber->s = xiaoqiang!
    pthread is created!
    fs@ubuntu:~/qiang/thread$ 
    

    例程总结:
        可以看出来main函数中的一个结构体传入了新建的线程中。
        线程包含了标识进程内执行环境必须的信息。他集成了进程中的所有信息都是对线程进行共享的,包括文本程序、程序的全局内存和堆内存、栈以及文件描述符

    例程5:
    程序目的:验证新建立的线程可以共享进程中的数据
    程序名称:pthread_share.c

    代码如下:

    #include <stdio.h>
    #include <pthread.h>
    
    static int a = 5;
    
    void *create(void *arg)
    {
    	printf("New pthread...\n");
    	printf("a = %d\n",a);
    
    	return (void *)0;
    }
    
    int main(int argc, const char *argv[])
    {
    	int error;
    	pthread_t id1;
    
    	error = pthread_create(&id1, NULL, create, NULL);
    	if(error != 0)
    	{
    		printf("new thread is not created!\n");
    		return -1;
    	}
    	sleep(1);
    	printf("New thread is created...\n");
    
    	return 0;
    }

    结果如下:

    fs@ubuntu:~/qiang/thread$ vi thread5.c
    fs@ubuntu:~/qiang/thread$ gcc -o thread5 thread5.c -lpthread
    fs@ubuntu:~/qiang/thread$ ./thread5
    New pthread...
    a = 5
    New thread is created...
    fs@ubuntu:~/qiang/thread$ 
    

    例程总结:
    可以看出来,我们在主线程更改了我们的全局变量a的值的时候,我们新建立的线程则打印出来了改变的值,可以看出可以访问线程所在进程中的数据信息。

    2、线程的终止
    如果进程中任何一个线程中调用exit,_Exit,或者是_exit,那么整个进程就会终止,
    与此类似,如果信号的默认的动作是终止进程,那么,把该信号发送到线程会终止进程。
    线程的正常退出的方式:
    (1) 线程只是从启动例程中返回,返回值是线程中的退出码
    (2) 线程可以被另一个进程进行终止
    (3) 线程自己调用pthread_exit函数

    两个重要的函数原型:

    include <pthread.h>
    void pthread_exit(void *rval_ptr);
    /*rval_ptr 线程退出返回的指针*/
    
    int pthread_join(pthread_t thread,void **rval_ptr);
       /*成功结束进程为0,否则为错误编码*/
    
    
    pthread_join使一个线程等待另一个线程结束。
    代码中如果没有pthread_join 主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。
    头文件 : #include <pthread.h>
    函数定义: int pthread_join(pthread_t thread, void **retval);
    描述 :pthread_join()函数,以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。
    参数 :thread: 线程 标识符,即线程ID,标识唯一线程。retval: 用户定义的指针,用来存储被等待线程的返回值。
    返回值 : 0代表成功。 失败,返回的则是错误号。

     

    例程6
    程序目的:线程正常退出,接受线程退出的返回码
    程序名称:pthread_exit.c
    执行代码如下:

    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    
    void *create(void *arg)
    {
    	printf("new thread is created ... \n");
    	return (void *)0;
    }
    
    int main(int argc,char *argv[])
    {
    	pthread_t tid;
    	int error;
    	void *temp;
    
    	error = pthread_create(&tid, NULL, create, NULL);
    
    	if( error )
    	{
    		printf("thread is not created ... \n");
    		return -1;
    	}
    	error = pthread_join(tid, &temp);
    
    	if( error )
    	{
    		printf("thread is not exit ... \n");
    		return -2;
    	}
    
    	printf("thread is exit code %d \n", (int )temp);
    									    
    	return 0;
    }

    执行结果如下:

    fs@ubuntu:~/qiang/thread$ vi thread6.c
    fs@ubuntu:~/qiang/thread$ gcc -o thread6 thread6.c -lpthread
    fs@ubuntu:~/qiang/thread$ ./thread6
    new thread is created ... 
    thread is exit code 0 
    fs@ubuntu:~/qiang/thread$ 
    

    例程总结:
    可以看出来,线程退出可以返回线程的int数值。

    线程退出不仅仅可以返回线程的int数值,还可以返回一个复杂的数据结构

    例程7
    程序目的:线程结束返回一个复杂的数据结构
    代码如下:
    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    
    struct menber
    {
    	int a;
    	char *b;
    }temp={8,"xiaoqiang"};
    
    void *create(void *arg)
    {
    	printf("new thread ... \n");
    	return (void *)&temp;
    }
    
    int main(int argc,char *argv[])
    {
    	int error;
    	pthread_t tid;
    	struct menber *c;
    
    	error = pthread_create(&tid, NULL, create, NULL);
    
    	if( error )
    	{
    		printf("new thread is not created ... \n");
    		return -1;
    	}
    	printf("main ... \n");
    
    	error = pthread_join(tid,(void *)&c);
    
    	if( error )
    	{
    		printf("new thread is not exit ... \n");
    		return -2;
    	}
    	printf("c->a = %d  \n",c->a);
    	printf("c->b = %s  \n",c->b);
    	sleep(1);
    	return 0;
    }
    
    执行结果如下:
    fs@ubuntu:~/qiang/thread$ gcc -o thread7 thread7.c -lpthread
    fs@ubuntu:~/qiang/thread$ ./thread7
    main ... 
    new thread ... 
    c->a = 8  
    c->b = xiaoqiang  
    fs@ubuntu:~/qiang/thread$ 
    
    例程总结:
    一定要记得返回的数据结构要是在这个数据要返回的结构没有释放的时候应用,如果数据结构已经发生变化,那返回的就不会是我们所需要的,而是脏数据。
     
    3、线程标识
          函数原型:
    #include <pthread.h>
    pthread_t pthread_self(void);
    pid_t getpid(void);
        getpid()用来取得目前进程的进程识别码,函数说明

    例程8
    程序目的:实现在新建立的线程中打印该线程的id和进程id
    代码如下:
    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h> /*getpid()*/
    
    void *create(void *arg)
    {
    	printf("New thread .... \n");
    	printf("This thread's id is %u  \n", (unsigned int)pthread_self());
    	printf("The process pid is %d  \n",getpid());
    	return (void *)0;
    }
    
    int main(int argc,char *argv[])
    {
    	pthread_t tid;
    	int error;
    
    	printf("Main thread is starting ... \n");
    
    	error = pthread_create(&tid, NULL, create, NULL);
    
    	if(error)
    	{
    		printf("thread is not created ... \n");
    		return -1;
    	}
    	printf("The main process's pid is %d  \n",getpid());
    	sleep(1);
    	return 0;
    }
    <span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>
    执行结果如下:
    fs@ubuntu:~/qiang/thread$ gcc -o thread8 thread8.c -lpthread
    fs@ubuntu:~/qiang/thread$ ./thread8
    Main thread is starting ... 
    The main process's pid is 4955  
    New thread .... 
    This thread's id is 3075853120  
    The process pid is 4955  
    fs@ubuntu:~/qiang/thread$ 
    




    展开全文
  • linux下C语言多线程编程实例.pdf
  • Linux多线程编程实例

    千次阅读 2010-11-03 12:09:00
    /********* ...多线程编程 **********/ #include #include #include void mythread() { int i; for(i=0;i;i++) printf("This is a pthread:/n"); pthread_exit("Thank you fo

    展开全文
  • Linux下C++多线程编程(入门实例

    万次阅读 多人点赞 2018-08-29 00:39:18
    C++ 多线程 多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。一般情况下,两种类型的多任务处理:基于进程和基于线程。 基于进程的多任务处理是程序的并发执行。 基于...

    C++ 多线程

    多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。一般情况下,两种类型的多任务处理:基于进程和基于线程

    • 基于进程的多任务处理是程序的并发执行。
    • 基于线程的多任务处理是同一程序的片段的并发执行。

    多线程程序包含可以同时运行的两个或多个部分。这样的程序中的每个部分称为一个线程,每个线程定义了一个单独的执行路径。

    本教程假设您使用的是 Linux 操作系统,我们要使用 POSIX 编写多线程 C++ 程序。POSIX Threads 或 Pthreads 提供的 API 可在多种类 Unix POSIX 系统上可用,比如 FreeBSD、NetBSD、GNU/Linux、Mac OS X 和 Solaris。

    创建线程

    下面的程序,我们可以用它来创建一个 POSIX 线程:

    #include <pthread.h>
    pthread_create (thread, attr, start_routine, arg) 

    在这里,pthread_create 创建一个新的线程,并让它可执行。下面是关于参数的说明:

    参数描述
    thread指向线程标识符指针。
    attr一个不透明的属性对象,可以被用来设置线程属性。您可以指定线程属性对象,也可以使用默认值 NULL。
    start_routine线程运行函数起始地址,一旦线程被创建就会执行。
    arg运行函数的参数。它必须通过把引用作为指针强制转换为 void 类型进行传递。如果没有传递参数,则使用 NULL。

    创建线程成功时,函数返回 0,若返回值不为 0 则说明创建线程失败。

    终止线程

    使用下面的程序,我们可以用它来终止一个 POSIX 线程:

    #include <pthread.h>
    pthread_exit (status) 

    在这里,pthread_exit 用于显式地退出一个线程。通常情况下,pthread_exit() 函数是在线程完成工作后无需继续存在时被调用。

    如果 main() 是在它所创建的线程之前结束,并通过 pthread_exit() 退出,那么其他线程将继续执行。否则,它们将在 main() 结束时自动被终止。

    实例

    以下简单的实例代码使用 pthread_create() 函数创建了 5 个线程,每个线程输出"Hello Runoob!":

    #include <iostream>
    // 必须的头文件
    #include <pthread.h>
     
    using namespace std;
     
    #define NUM_THREADS 5
     
    // 线程的运行函数
    void* say_hello(void* args)
    {
        cout << "Hello Runoob!" << endl;
        return 0;
    }
     
    int main()
    {
        // 定义线程的 id 变量,多个变量使用数组
        pthread_t tids[NUM_THREADS];
        for(int i = 0; i < NUM_THREADS; ++i)
        {
            //参数依次是:创建的线程id,线程参数,调用的函数,传入的函数参数
            int ret = pthread_create(&tids[i], NULL, say_hello, NULL);
            if (ret != 0)
            {
               cout << "pthread_create error: error_code=" << ret << endl;
            }
        }
        //等各个线程退出后,进程才结束,否则进程强制结束了,线程可能还没反应过来;
        pthread_exit(NULL);
    }

    使用 -lpthread 库编译下面的程序:

    $ g++ test.cpp -lpthread -o test.o

    现在,执行程序,将产生下列结果:

    $ ./test.o
    Hello Runoob!
    Hello Runoob!
    Hello Runoob!
    Hello Runoob!
    Hello Runoob!

    以下简单的实例代码使用 pthread_create() 函数创建了 5 个线程,并接收传入的参数。每个线程打印一个 "Hello Runoob!" 消息,并输出接收的参数,然后调用 pthread_exit() 终止线程。

    实例

    //文件名:test.cpp
     
    #include <iostream>
    #include <cstdlib>
    #include <pthread.h>
     
    using namespace std;
     
    #define NUM_THREADS     5
     
    void *PrintHello(void *threadid)
    {  
       // 对传入的参数进行强制类型转换,由无类型指针变为整形数指针,然后再读取
       int tid = *((int*)threadid);
       cout << "Hello Runoob! 线程 ID, " << tid << endl;
       pthread_exit(NULL);
    }
     
    int main ()
    {
       pthread_t threads[NUM_THREADS];
       int indexes[NUM_THREADS];// 用数组来保存i的值
       int rc;
       int i;
       for( i=0; i < NUM_THREADS; i++ ){      
          cout << "main() : 创建线程, " << i << endl;
          indexes[i] = i; //先保存i的值
          // 传入的时候必须强制转换为void* 类型,即无类型指针        
          rc = pthread_create(&threads[i], NULL, 
                              PrintHello, (void *)&(indexes[i]));
          if (rc){
             cout << "Error:无法创建线程," << rc << endl;
             exit(-1);
          }
       }
       pthread_exit(NULL);
    }

    现在编译并执行程序,将产生下列结果:

    $ g++ test.cpp -lpthread -o test.o
    $ ./test.o
    main() : 创建线程, 0
    main() : 创建线程, 1
    Hello Runoob! 线程 ID, 0
    main() : 创建线程, Hello Runoob! 线程 ID, 21
    
    main() : 创建线程, 3
    Hello Runoob! 线程 ID, 2
    main() : 创建线程, 4
    Hello Runoob! 线程 ID, 3
    Hello Runoob! 线程 ID, 4

    向线程传递参数

    这个实例演示了如何通过结构传递多个参数。您可以在线程回调中传递任意的数据类型,因为它指向 void,如下面的实例所示:

    实例

    #include <iostream>
    #include <cstdlib>
    #include <pthread.h>
     
    using namespace std;
     
    #define NUM_THREADS     5
     
    struct thread_data{
       int  thread_id;
       char *message;
    };
     
    void *PrintHello(void *threadarg)
    {
       struct thread_data *my_data;
     
       my_data = (struct thread_data *) threadarg;
     
       cout << "Thread ID : " << my_data->thread_id ;
       cout << " Message : " << my_data->message << endl;
     
       pthread_exit(NULL);
    }
     
    int main ()
    {
       pthread_t threads[NUM_THREADS];
       struct thread_data td[NUM_THREADS];
       int rc;
       int i;
     
       for( i=0; i < NUM_THREADS; i++ ){
          cout <<"main() : creating thread, " << i << endl;
          td[i].thread_id = i;
          td[i].message = (char*)"This is message";
          rc = pthread_create(&threads[i], NULL,
                              PrintHello, (void *)&td[i]);
          if (rc){
             cout << "Error:unable to create thread," << rc << endl;
             exit(-1);
          }
       }
       pthread_exit(NULL);
    }

    当上面的代码被编译和执行时,它会产生下列结果:

    $ g++ -Wno-write-strings test.cpp -lpthread -o test.o
    $ ./test.o
    main() : creating thread, 0
    main() : creating thread, 1
    Thread ID : 0 Message : This is message
    main() : creating thread, Thread ID : 21
     Message : This is message
    main() : creating thread, 3
    Thread ID : 2 Message : This is message
    main() : creating thread, 4
    Thread ID : 3 Message : This is message
    Thread ID : 4 Message : This is message

    连接和分离线程

    我们可以使用以下两个函数来连接或分离线程:

    pthread_join (threadid, status) 
    pthread_detach (threadid) 

    pthread_join() 子程序阻碍调用程序,直到指定的 threadid 线程终止为止。当创建一个线程时,它的某个属性会定义它是否是可连接的(joinable)或可分离的(detached)。只有创建时定义为可连接的线程才可以被连接。如果线程创建时被定义为可分离的,则它永远也不能被连接。

    这个实例演示了如何使用 pthread_join() 函数来等待线程的完成。

    实例

    #include <iostream>
    #include <cstdlib>
    #include <pthread.h>
    #include <unistd.h>
     
    using namespace std;
     
    #define NUM_THREADS     5
     
    void *wait(void *t)
    {
       int i;
       long tid;
     
       tid = (long)t;
     
       sleep(1);
       cout << "Sleeping in thread " << endl;
       cout << "Thread with id : " << tid << "  ...exiting " << endl;
       pthread_exit(NULL);
    }
     
    int main ()
    {
       int rc;
       int i;
       pthread_t threads[NUM_THREADS];
       pthread_attr_t attr;
       void *status;
     
       // 初始化并设置线程为可连接的(joinable)
       pthread_attr_init(&attr);
       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
     
       for( i=0; i < NUM_THREADS; i++ ){
          cout << "main() : creating thread, " << i << endl;
          rc = pthread_create(&threads[i], NULL, wait, (void *)&i );
          if (rc){
             cout << "Error:unable to create thread," << rc << endl;
             exit(-1);
          }
       }
     
       // 删除属性,并等待其他线程
       pthread_attr_destroy(&attr);
       for( i=0; i < NUM_THREADS; i++ ){
          rc = pthread_join(threads[i], &status);
          if (rc){
             cout << "Error:unable to join," << rc << endl;
             exit(-1);
          }
          cout << "Main: completed thread id :" << i ;
          cout << "  exiting with status :" << status << endl;
       }
     
       cout << "Main: program exiting." << endl;
       pthread_exit(NULL);
    }

    当上面的代码被编译和执行时,它会产生下列结果:

    main() : creating thread, 0
    main() : creating thread, 1
    main() : creating thread, 2
    main() : creating thread, 3
    main() : creating thread, 4
    Sleeping in thread 
    Thread with id : 4  ...exiting 
    Sleeping in thread 
    Thread with id : 3  ...exiting 
    Sleeping in thread 
    Thread with id : 2  ...exiting 
    Sleeping in thread 
    Thread with id : 1  ...exiting 
    Sleeping in thread 
    Thread with id : 0  ...exiting 
    Main: completed thread id :0  exiting with status :0
    Main: completed thread id :1  exiting with status :0
    Main: completed thread id :2  exiting with status :0
    Main: completed thread id :3  exiting with status :0
    Main: completed thread id :4  exiting with status :0
    Main: program exiting.

    c++ 11 之后有了标准的线程库:

    #include <iostream>
    
    #include <thread>
    
    std::thread::id main_thread_id = std::this_thread::get_id();
    
    void hello()  
    {
        std::cout << "Hello Concurrent World\n";
        if (main_thread_id == std::this_thread::get_id())
            std::cout << "This is the main thread.\n";
        else
            std::cout << "This is not the main thread.\n";
    }
    
    void pause_thread(int n) {
        std::this_thread::sleep_for(std::chrono::seconds(n));
        std::cout << "pause of " << n << " seconds ended\n";
    }
    
    int main() {
        std::thread t(hello);
        std::cout << t.hardware_concurrency() << std::endl;//可以并发执行多少个(不准确)
        std::cout << "native_handle " << t.native_handle() << std::endl;//可以并发执行多少个(不准确)
        t.join();
        std::thread a(hello);
        a.detach();
        std::thread threads[5];                         // 默认构造线程
    
        std::cout << "Spawning 5 threads...\n";
        for (int i = 0; i < 5; ++i)
            threads[i] = std::thread(pause_thread, i + 1);   // move-assign threads
        std::cout << "Done spawning threads. Now waiting for them to join:\n";
        for (auto &thread : threads)
            thread.join();
        std::cout << "All threads joined!\n";
    }

    之前一些编译器使用 C++11 的编译参数是 -std=c++11

    g++ -std=c++11 test.cpp -lpthread

    原文链接:http://www.runoob.com/cplusplus/cpp-multithreading.html

    Windows多线程可参考:

     

    http://www.runoob.com/w3cnote/cpp-multithread-demo.html

     

    展开全文
  • linux c 开发中多线程的典型实例,可在linux平台直接运行,通过实践熟悉理解多线程工作原理。
  • 三个多线程经典代码只需要5分 转别人的,没分下载了 混点分,请多多支持
  • linux下C语言多线程编程实例.doc
  • 主要介绍了Linux多线程编程快速入门,涉及到了线程基本知识,线程标识,线程创建,线程终止,管理线程的终止等相关内容,小编觉得还是挺不错的,这里分享给大家,需要的朋友可以参考下
  • Linux下, 线程的互斥量数据类型是pthread_mutex_t. 在使用前, 要对它进行初始化: 对于静态分配的互斥量, 可以把它设置为PTHREAD_MUTEX_INITIALIZER, 或者调用pthread_mutex_init. 对于动态分配的互斥量, 在申请...
  • linux下C语言多线程编程实例.docx
  • 使用多线程进行串口编程,获取串口数据,利用互斥锁和信号量在不同的线程中安全地操作数据,希望该demo能帮助你快速理解并掌握上述知识。
  • 本篇文章主要介绍了Linux多线程编程,详解的介绍了为什么要使用线程,使用线程的理由和优点等,有需要的可以了解一下。
  • Linux多线程编程实例解析

    千次阅读 2016-04-07 20:01:02
    一个线程可以含有线程,这也是为了提高系统资源利用率,线程的引入有其必然的优势,线程有自己的堆栈。记得操作系统的书籍上有一句经典的话”进程——资源分配的最小单位,线程——程序执行的最小单位“。一个...
  • linux epoll多线程编程 例子
  • linux下C语言多线程编程实例[归纳].pdf
  • Linux多线程编程 多核编程》由会员分享,可在线阅读,更多相关《Linux多线程编程 多核编程(28页珍藏版)》请在人人文库网上搜索。1、Linux多线程编程,IEEE POSIX 标准 p1003.1c (Pthreads) 定义了处理线程的一系列C...
  • Linux下c语言多线程编程

    千次阅读 2022-03-30 14:09:16
    创建线程函数pthread_create()和等待线程函数pthread_join()的用法。 注意:在创建线程pthread_create()之前,要先定义线程标识符: pthread_t 自定义线程名; 例子1:创建线程以及等待线程执行完毕。 #include <...
  • linux epoll多线程编程实例,在Linux下编译通过

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 66,143
精华内容 26,457
关键字:

linux多线程编程实例