在编译多线程程序的时候,需要连接libpthread文件:

gcc pthread.c  -o  pthread  -lpthread;

所有线程一律平等,没有父子关系,线程属于进程。

创建线程用 pthread_create()函数,其函数原型是:

#include<pthread.h>

int pthread_create(pthread_t *restrict thread,const pthread_attr_t *restric attr,void* (*start_routine)(void *),void *restrict arg);

第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,大多数情况下,

我们不需要设置线程的属性,那么空指针 NULL 就可以了,第三个参数是线程运行函数的起

始地址,最后一个参数是运行函数的参数。

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

创建代码如下:

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
void *thread(void*agrv)
{
int i;
for(i=;i<;i++)
{
printf("run pthread..\n");//sleep(1); }
} int main()
{ int i;
int ret;
pthread_t pthid;//创建线程标识符
ret=pthread_create(&pthid,NULL,thread,NULL);
if(ret!=)
printf("create pthread error!\n"); for(i=;i<;i++)
{
printf("run main..\n");//sleep(1); }
}

注释掉sleep(1)后输出结果为:

run main..
run main..
run main..
run main..
run main..

这是因为主线程结束以后进程就直接结束了。我们可以加一个sleep函数,等待子线程的完成。

加入sleep(1)后结果为:

run main..
run pthread..
run main..
run pthread..
run main..
run pthread..
run main..
run pthread..
run main..
run pthread..

可以看出两个线程的输出是交替的,当一个线程进入睡眠时,另外一个线程就会被调度执行。

接下来修改一下程序,让子进程里面的程序循环10次:此时,由于在main函数中,主线程输出5次进程就会结束,所以子线程里面剩余的输出将不会进行,输出结果会和上面的一样。我们可以添加一个等待函数,注意的是,一个线程不能被多个线程等待!!

pthread_join():这个函数是主线程用于等待子线程结束的,返回值为int型;其函数原型是:

#include<pthread.h>

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

第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。

代码为:

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
void *thread(void*agrv)
{
int i;
for(i=;i<;i++)
{
printf("run pthread..\n");sleep(); }
} int main()
{ int i;
int ret;
pthread_t pthid;//创建线程标识符
ret=pthread_create(&pthid,NULL,thread,NULL);
// pthread_join( pthid,NULL); // 等待函数放在这会先把子线程打印完毕再打印主线程里面的内容
if(ret!=)
printf("create pthread error!\n"); for(i=;i<;i++)
{
printf("run main..\n");sleep(); }
pthread_join(pthid,NULL);//一般放在末尾
}

输出结果为:

run main..
run pthread..
run main..
run pthread..
run main..
run pthread..
run main..
run pthread..
run main..
run pthread..
run pthread..
run pthread..
run pthread..
run pthread..
run pthread..

一个线程的结束有两种途径,一种是和示例 3-10 一样,函数结束了,调用它的线程也

就结束了:另一种方式是通过函数 pthread_exit()来实现。它的函数原型为:

#include<pthread.h>

void pthread_exit(void *value_ptr)

函数的参数是函数的返回代码,只要 pthread_join 中的第二个参数 value_ptr 不是NULL,这个值将被传递给主线程。

代码如下:

 #include<stdio.h>
#include<pthread.h>
#include<unistd.h>
void *thread(void*agrv)
{
int i;
for(i=;i<;i++)
{
printf("run pthread..\n");sleep(); }
} int main()
{ int i;
int ret;
pthread_t pthid;//创建线程标识符
ret=pthread_create(&pthid,NULL,thread,NULL); if(ret!=)
printf("create pthread error!\n"); pthread_exit(NULL);//主线程结束,但是程序并没有结束,会打印子线程的内容 for(i=;i<;i++)
{
printf("run main..\n");sleep(); }
}

输出结果为:

run pthread..
run pthread..
run pthread..
run pthread..
run pthread..
run pthread..
run pthread..
run pthread..
run pthread..
run pthread..

Linux 线程编程1.0的更多相关文章

  1. Linux 线程编程2.0——线程同步-互斥锁

    当我们需要控制对共享资源的存取的时候,可以用一种简单的加锁的方法来控制.我们可以创建一个读/写程序,它们共用一个共享缓冲区,使用互斥锁来控制对缓冲区的存取. 函数 pthread_mutex_init ...

  2. Linux 线程编程3.0

    #include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h& ...

  3. Linux线程编程之信号处理

    前言 Linux多线程环境中的信号处理不同于进程的信号处理.一方面线程间信号处理函数的共享性使得信号处理更为复杂,另一方面普通异步信号又可转换为同步方式来简化处理. 本文首先介绍信号处理在进程中和线程 ...

  4. linux 线程编程详解

    1.线程的概念: 线程和进程有一定的相似性,通常称为轻量级的进程 同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等.但同一进程中的多个线程都有自身控制流 (它 ...

  5. Linux线程编程之生产者消费者问题

    前言 本文基于顺序循环队列,给出Linux生产者/消费者问题的多线程示例,并讨论编程时需要注意的事项.文中涉及的代码运行环境如下: 本文假定读者已具备线程同步的基础知识. 一  顺序表循环队列 1.1 ...

  6. Linux线程编程之生产者消费者问题【转】

    转自:http://www.cnblogs.com/clover-toeic/p/4029269.html 前言 本文基于顺序循环队列,给出Linux生产者/消费者问题的多线程示例,并讨论编程时需要注 ...

  7. Linux多任务编程——线程

    线程基础 △ 由于进程的地址空间是私有的,因此在进行上下文切换时,系统开销比较大 △ 在同一个进程中创建的线程共享该进程的地址空间 △ 通常线程值得是共享相同地址空间的多个任务 △ 每个线程的私有这些 ...

  8. linux高级编程基础系列:线程间通信

    linux高级编程基础系列:线程间通信 转载:原文地址http://blog.163.com/jimking_2010/blog/static/1716015352013102510748824/ 线 ...

  9. Linux系统编程——线程私有数据

    在多线程程序中.常常要用全局变量来实现多个函数间的数据共享.因为数据空间是共享的,因此全局变量也为全部线程共同拥有. 測试代码例如以下: #include <stdio.h> #inclu ...

随机推荐

  1. junit 基础使用

    junit百度百科: JUnit是一个Java语言的单元测试框架.它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个. JU ...

  2. Linux 实时查看tomcat 日志--less命令

    查看tomcat日志通常用 tail -n  或者 tail -f 或者grep 或者 vi cat等命令去查看异常信息,但是日志是在不停地刷屏,tail是动态的在变的,我们往往期望从日志最后一行往前 ...

  3. Python实践练习:强口令检测

    题目: 写一个函数,它使用正则表达式,确保传入的口令字符串是强口令.强口令的定义是:长度不少于 8 个字符,同时包含大写和小写字符,至少有一位数字.你可能需要用多个正则表达式来测试该字符串,以保证它的 ...

  4. leetcode17

    回溯法,深度优先遍历(DFS) public class Solution { int[] x; int N; string DIGITS; Dictionary<char, List<s ...

  5. LevelDB源码分析-编码

    编码(util/coding.h util/coding.cc) LevelDB将整型编码为二进制字符串的形式,同时又能够和ASCII字符区分. 首先是定长编码: void EncodeFixed32 ...

  6. git本地推送远程

    第一次将本地映射到已经存在的仓库 https://techoverflow.net/2017/08/09/how-to-solve-git-fatal-no-configured-push-desti ...

  7. 在delphi中XLSReadWriteII.组件的应用实例(1)

    第三方组件:XLSReadWriteII.v.5.20.67_XE3 实例源码如下: unit Unit1; interface uses Winapi.Windows, Winapi.Message ...

  8. Java中的包装数据类型

    基本类型 包装器类型 boolean Boolean char Character int Integer byte Byte short Short long Long float Float do ...

  9. 移动端过禁止输入emoji表情实现方案

    最近手头上的项目有一个需求就是输入框不能输入表情,然后就各种在网上找资料,网上好多人给的方案是: str = str.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uD ...

  10. 微擎系统jssdk系统快速签名变量

    jssdkconfig = {php echo json_encode($_W['account']['jssdkconfig']);} || { jsApiList:[] };    jssdkco ...