linux多线程编程

来源:互联网 发布:魔兽世界7.0优化 编辑:程序博客网 时间:2024/05/16 11:44

进程具有以下特点:
系统中程序执行和资源分配的基本单位
每个进程有自己的数据段、代码段和堆栈段
在进行切换时需要有比较复杂的上下文切换

线程具有以下特点:
减少处理机的空转时间,支持多处理器以及减少上下文切换开销, 比创建进程小很多
进程内独立的一条运行路线
处理器调度的最小单元,也称为轻量级进程
可以对进程的内存空间和资源进行访问,并与同一进程中的其他线程共享
线程相关的执行状态和存储变量放在线程控制表内
一个进程可以有多个线程,有多个线程控制表及堆栈寄存器,共享一个用户地址空间

多线程同步问题
线程共享进程的资源和地址空间
任何线程对系统资源的操作都会给其他线程带来影响

进程ID在整个系统中是唯一的
线程ID只在它所属的进程环境中有效

#include <pthread.h>
pthread_t pthread_self(void);返回值是调用线程的线程id。
int pthread_equal(pthread_t tid1,pthread_t tid2);两个线程id如果相等返回非0.
pthread_t类型通常用结构来表示,linux使用无符号长整型数表示,但不能作为整数处理。
#include <stdio.h>
 #include <stdlib.h>
 #include <pthread.h>
 
 int main(){
     pthread_t thread_id;
 
     thread_id=pthread_self(); // 返回调用线程的线程ID
     printf("Thread ID: %lu.\n",thread_id);
 
     if (pthread_equal(thread_id,pthread_self())) {
 //    if (thread_id==0) {
         printf("Equal!\n");
     } else {
         printf("Not equal!\n");
     }
     return 0;
 }
线程编程,操作用户空间中的线程
创建线程
?调用该线程函数的入口点
?使用函数pthread_create(),线程创建后,就开始运行相关的线程函数
pthread_create是UNIX,linux环境创建线程函数
int pthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg);
若成功则返回0,否则返回出错编号
返回成功时,由tidp指向的内存单元被设置为新创建线程的线程ID。attr参数用于指定各种不同的线程属性。新创建的线程从start_rtn函数的地址开始运行,该函数只有一个万能指针参数arg,如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。
linux下用C开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread。
第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的起始地址。
最后一个参数是运行函数的参数。
另外,在编译时注意加上-lpthread参数,以调用链接库。因为pthread并非Linux系统的默认库,而是posix线程库,在Linux中将其作为一个库来使用,因此加上 -lpthread(或-pthread)以显示的链接该库。函数在执行错误时的错误信息将作为返回值返回,并不修改系统全局变量errno,当然也无法使用perror()打印错误信息。

示例:
//打印线程 IDs
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

pthread_t ntid;

void printids(const char *s)
{
pid_t pid; //进程id
pthread_t tid;
   pid = getpid();
   tid = pthread_self();
printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int) pid,
(unsigned int) tid, (unsigned int) tid);
}

void *thr_fn(void *arg)
{
  printids("new thread: ");
  return ((void *) 0);
}

int main(void)
{
int err;
   err = pthread_create(&ntid, NULL, thr_fn, NULL);
   if (err != 0)printf("can't create thread: %s\n", strerror(err));
   printids("main thread:");
sleep(1);
exit(0);
}
编译运行
$ gcc main.c -lpthread -o main
$ ./main
main thread: pid 7398 tid 3084450496 (0xb7d8fac0)
new thread: pid 7398 tid 3084446608 (0xb7d8eb90)

在线程函数运行完后,该线程也就退出了
使用函数pthread_exit(),这是线程的主动行为
但是不能使用exit()退出。
使调用进程终止,所有线程都终止了
由于一个进程中的多个线程是共享数据段的,通常在线程退出之后,退出线程所占用的资源并不会随着线程的终止而得到释放。
类似进程的wait()/waitpid()函数,用于将当前线程挂起来等待线程的结束
是一个线程阻塞的函数,调用它的线程一直等待到被等待的线程结束为止
函数返回时,被等待线程的资源就被收回

原创粉丝点击