注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Under the bule sky

Get what I want "cause I ask for it.

 
 
 

日志

 
 

Linux进程&线程--线程及相关函数Ⅱ  

2014-08-11 19:43:34|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
线程:轻量级的进程,是调度的最小单位。线程是共享同一进程地址空间多个可独立被调度运行的任务。

6.Linux进程线程--线程及相关函数Ⅱ - 戴↑Ω听歌 - ∞
 
一、 多线程与多进程的区别
不同点:
1.在一个进程中创建的多个线程,共享同一个进程的资源,各线程独立被内核调度 。
2.多个进程是独立地址空间。线程间共享同一个进程的地址空间,进程间是独立的地址空间。

相同点:
1.都参与统一的调度。
2.都有自己的ID,一组寄存器的值。

二、线程间共享资源和私有资源
共享资源:全局变量,打开文件获得文件描述符。 
私有资源:私有TID,私有栈 

所有的程序都有一个主线程(main thread),主线程是进程的控制流或执行线程。 在多线程程序中,主线程可以创建一个或多个对等线程(peer thread), 从这个创建时间点开始,这些线程就开始并发执行。 主线程和对等线程的区别其中之一是,主线程总是进程中第一个运行的线程。

三、线程的操作
NPTL 线程库中函数大多以pthread_开头,线程库中函数大都返回errno而不是置errno。
调用NPTL中函数需要加上 pthread.h头文件。
编译和链接需加上 -pthread。
1.创建一个线程

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

功能:创建一个线程 
参数: thread 获得线程ID 
  attr 线程的属性,通常为NULL表示使用默认属性 
  start_routine 线程的执行函数,即线程执行的代码,采用回调方式执行线程函数 
  arg 给线程函数传递的参数 
返回值: 成功返回0,失败返回错误码 
注意:pthread_t为unsigned long类型
6.Linux进程线程--线程及相关函数Ⅱ - 戴↑Ω听歌 - ∞
 
例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>

#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

void *thread_fun(void *arg)
{
while(1)
{
printf("\t\tPID = %d thread1 tid = %lu\n",getpid(),pthread_self());

sleep(1);
}

return NULL;
}


int main(int argc, const char *argv[])
{
pthread_t tid[1];
int s = 0;

if((s = pthread_create(&tid[0],NULL,thread_fun,NULL)) != 0)
handle_error_en(s,"pthread_create");

while(1);
return 0;
}

建议用法:(定义宏函数输出错误信息)

#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
---------------------------------------------------------------------
void *thread_func(void *arg)
{
char *p = (char *)arg;
}

s = pthread_create(&thr, NULL, &thread_func, buf);
if (s != 0)
handle_error_en(s, "pthread_create");

2.获得当前线程的ID

pthread_t pthread_self(void);

功能:获得当前线程的tid ,类似进程中的getpid(2),该函数总是成功。
3.线程的退出

void pthread_exit(void *retval);

功能:结束当前线程的执行 
参数:retval  给等待的线程带回一个地址值,如果没有值带回,写为NULL 
返回值:无

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>

#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

void *thread_fun(void *arg)
{
while(1)
{
printf("\t\tPID = %d thread1 tid = %lu\n",getpid(),pthread_self());
sleep(1);
}
return NULL;
}

void *thread_fun1(void *arg)
{
/*int *pval = arg;*/
int val = *(int *)arg;
int i = 5;

while(i--)
{
printf("\tval = %d PID = %d thread2 tid = %lu\n",val++,getpid(),pthread_self());
/*printf("\tval = %d PID = %d thread2 tid = %lu\n",(*pval)++,getpid(),pthread_self());*/

sleep(1);
}

//pthread_exit(NULL);
/*exit(EXIT_SUCCESS);*/

return NULL;
}

int main(int argc, const char *argv[])
{
pthread_t tid[2];
int s = 0;
int val = 10;
int n = 0;

if((s = pthread_create(&tid[0],NULL,thread_fun,NULL)) != 0)
handle_error_en(s,"pthread_create");

if((s = pthread_create(&tid[1],NULL,thread_fun1,&val)) != 0)
handle_error_en(s,"pthread_create");

n = 3;
while(n--)
{
printf("PID = %d main thread tid = %lu val = %d\n",getpid(),pthread_self(),val);
sleep(1);
}
pthread_exit(NULL);

while(1);
return 0;
}


4.线程连接
等待线程退出,作用类似进程中的wait(2)系统调用,可实现线程同步。

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

功能:阻塞方式等待指定的线程退出,并且释放结束线程未释放的资源(例如:线程的私有栈资源等)
参数:
    thread  线程TID 
    retval  获得pthread_exit带回的地址值  

返回值:
成功返回0,失败返回错误码

注意:如果等待的线程没有退出,则调用pthread_join的线程会阻塞

例: thread1 中调用pthread_exit();

thread2 中调用pthread_join();

thread1 :tid1

    static int val;

    val = *(int *)arg;


    pthread_exit(&val);


    thread2 :tid2

    int *retval = NULL;

    pthread_join(tid1,(void **)&retval);

    <thread2> *retval <=> <thread1> val


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>

#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

void *thread_fun(void *arg)
{
while(1)
{
printf("\t\tPID = %d thread1 tid = %lu\n",getpid(),pthread_self());

sleep(1);
}

return NULL;
}

void *thread_fun1(void *arg)
{
/*int *pval = arg;*/
static int val = 10;//*(int *)arg;
int i = 5;

while(i--)
{
printf("\tval = %d PID = %d thread2 tid = %lu\n",val++,getpid(),pthread_self());
/*printf("\tval = %d PID = %d thread2 tid = %lu\n",(*pval)++,getpid(),pthread_self());*/

sleep(1);
}

pthread_exit(&val);

//pthread_exit(NULL);
/*exit(EXIT_SUCCESS);*/

return NULL;
}

int main(int argc, const char *argv[])
{
pthread_t tid[2];
int s = 0;
int val = 10;
int n = 0;
int *retval = NULL;

if((s = pthread_create(&tid[0],NULL,thread_fun,NULL)) != 0)
handle_error_en(s,"pthread_create");

if((s = pthread_create(&tid[1],NULL,thread_fun1,&val)) != 0)
handle_error_en(s,"pthread_create");

if((s = pthread_join(tid[1],(void **)&retval)) != 0)
handle_error_en(s,"pthread_join");

printf("terminated thread2 return val = %d\n",*retval);

n = 30;
while(n--)
{
printf("PID = %d main thread tid = %lu val = %d\n",getpid(),pthread_self(),val);
sleep(1);
}

return 0;
}



5.线程的分离
通知系统当线程结束,可以自动回收线程未释放的资源 ,如果不分离,当子进程执行完之后会成为僵尸线程,需要等到主线程执行完之后才会收尸,如果分离之后,当子进程执行完就会通知系统来收尸了。。。。
如果线程没有终止,pthread_detach()函数也不会令其终止。
int pthread_detach(pthread_t thread);

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>

#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

void *thread_fun(void *arg)
{
while(1)
{
printf("\t\tPID = %d thread1 tid = %lu\n",getpid(),pthread_self());

sleep(1);
}
return NULL;
}

void *thread_fun1(void *arg)
{
/*int *pval = arg;*/
static int val = 10;//*(int *)arg;
int i = 5;
while(i--)
{
printf("\tval = %d PID = %d thread2 tid = %lu\n",val++,getpid(),pthread_self());
/*printf("\tval = %d PID = %d thread2 tid = %lu\n",(*pval)++,getpid(),pthread_self());*/

sleep(1);
}
pthread_exit(&val);

//pthread_exit(NULL);
/*exit(EXIT_SUCCESS);*/
return NULL;
}

int main(int argc, const char *argv[])
{
pthread_t tid[2];
int s = 0;
int val = 10;
int n = 0;
int *retval = NULL;

if((s = pthread_create(&tid[0],NULL,thread_fun,NULL)) != 0)
handle_error_en(s,"pthread_create");
if((s = pthread_create(&tid[1],NULL,thread_fun1,&val)) != 0)
handle_error_en(s,"pthread_create");
pthread_detach(tid[1]);

//if((s = pthread_join(tid[1],(void **)&retval)) != 0)
// handle_error_en(s,"pthread_join");

printf("terminated thread2 return val = %d\n",*retval);

n = 10;
while(n--)
{
printf("PID = %d main thread tid = %lu val = %d\n",getpid(),pthread_self(),val);
sleep(1);
}
if((s = pthread_cancel(tid[0])) != 0)
handle_error_en(s,"pthread_cancel");

sleep(3);
return 0;
}



6.请求取消一个线程执行
在一个进程中请求取消另一个进程,注意,这里只是请求取消,就像汽车在高速公路上行驶,不是任何地方都可以加油,得到服务区或是加油站,取消进程也一样,得到合适的点才能取消。
int pthread_cancel(pthread_t thread);

  评论这张
 
阅读(7)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017