当前位置:首页 > 工业控制 > 电子设计自动化
[导读]作者:曹忠明,华清远见嵌入式学院讲师。 一、线程控制 上一节我们讲了使用互斥量实现线程的同步,这里我们介绍一下另外一种常用的方法,POSIX提供的无名信号量sem,PV原语是对整数计数器信号量sem的操作,P操作判断s

作者:曹忠明,华清远见嵌入式学院讲师。

一、线程控制

上一节我们讲了使用互斥量实现线程的同步,这里我们介绍一下另外一种常用的方法,POSIX提供的无名信号量sem,PV原语是对整数计数器信号量sem的操作,P操作判断sem资源数是否为0,不为0则进行P操作,一次P操作可使sem减一,而一次V操作可使sem加一。下面是POSIX提供的一些接口函数:

1、信号量初始化

#include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);

函数参数:

sem:信号量

pshared:一个参数一般为0,表示同一个进程中的线程共享一个信号量。

value:信号量资源个数

2、其余函数

int sem_wait (sem_t* sem);

int sem_trywait (sem_t* sem);

int sem_post (sem_t* sem);

int sem_getvalue (sem_t* sem);

int sem_destroy (sem_t* sem);

sem_wait和sem_trywait相当于P操作,它们都能将信号量的值减一,两者的区别在于若信号量的值小于零时,sem_wait将会阻塞进程,而sem_trywait则会立即返回。

sem_post相当于V操作,它将信号量的值加一,同时发出唤醒的信号给等待的进程(或线程)。

sem_getvalue 得到信号量的值。

sem_destroy 摧毁信号量。

下面用一个例程说明信号量的使用:

#include <stdio.h>

#include <pthread.h>

#include <sys/types.h>

#include <sys/syscall.h>

#include <unistd.h>

#include <semaphore.h>

sem_t sem;

pid_t gettid(void)

{

return syscall(SYS_gettid);

}

void *thread_a(void *arg)

{

printf("thread a entern");

sem_wait(&sem); //sem - 1

printf("thread a P operationn");

sleep(10);

sem_post(&sem); //sem + 1

printf("thread a V operationn");

}

void *thread_b(void *arg)

{

printf("thread b entern");

sem_wait(&sem); //sem - 1

printf("thread b P operationn");

sleep(10);

sem_post(&sem); //sem + 1

printf("thread b V operationn");

}

int main(int argc, char **argv)

{

pthread_t tid_a,tid_b;

int err;

sem_init(&sem, 0, 1);

err = pthread_create(&tid_a,NULL,thread_a,NULL);

if(err < 0)

{

perror("pthread_create thread_a");

}

err = pthread_create(&tid_b,NULL,thread_b,NULL);

if(err < 0)

{

perror("pthread_create thread_a");

}

sleep(30);

sem_destroy(&sem);

printf("the main closen");

return 0;

}

二、POSIX tid和linux tid

前面我们说创建线程的时候提到一个函数pthread_self,这个函数使POSIX线程库中的一个函数,通过这个函数可以获得线程的ID,可是我们打印出来这个ID会发现这个ID是一个很大的数字。没有得到我们想象的一个数字,其实这个ID是POSIX线程库提供的一个数字,而linux内核中也为这个线程提供了一个ID,这个ID可以通过gettid获得,gettid是linux内核提供的一个系统调用,Glibc没有封装函数,只能通过系统调用实现。

POSIX:

#include <pthread>

pthread_t pthread_self(void);

linux系统调用:

#include <sys/types.h>

#include <sys/syscall.h>

pid_t gettid(void)

{

return syscall(SYS_gettid);

}

下面我们通过一个例程看下这两个函数的区别。

#include <stdio.h>

#include <pthread.h>

#include <sys/types.h>

#include <sys/syscall.h>

#include <unistd.h>

pid_t gettid(void)

{

return syscall(SYS_gettid);

}

void *thread_a(void *arg)

{

printf("thread a entern");

pthread_t posix_tid;

pid_t linux_tid;

pid_t pid;

posix_tid = pthread_self();

linux_tid = gettid();

pid = getpid();

printf("pid = %x, posix_tid = %x, linux_tid = %xn", pid, posix_tid, linux_tid);

}

void *thread_b(void *arg)

{

printf("thread b entern");

pthread_t posix_tid;

pid_t linux_tid;

pid_t pid;

posix_tid = pthread_self();

linux_tid = gettid();

pid = getpid();

printf("pid = %x, posix_tid = %x, linux_tid = %xn", pid, posix_tid, linux_tid);

}

int main(int argc, char **argv)

{

pthread_t tid_a,tid_b;

int err;

err = pthread_create(&tid_a,NULL,thread_a,NULL);

if(err < 0)

{

perror("pthread_create thread_a");

}

err = pthread_create(&tid_b,NULL,thread_b,NULL);

if(err < 0)

{

perror("pthread_create thread_a");

}

sleep(5);

printf("the main closen");

return 0;

}

程序运行结果:

thread a enter

pid = 3b89, posix_tid = b7fd4b90, linux_tid = 3b8a

thread b enter

pid = 3b89, posix_tid = b75d3b90, linux_tid = 3b8b

the main close

通过这个函数我们可以发现posix提供的这个ID不是很有规律,而linux内核为线程提供的ID是经跟在主进程进程号的数字,如上面程序中主进程ID为3b89而两个线程的ID分别为3b8a,3b8b。

“本文由华清远见http://www.embedu.org/index.htm提供”



来源:华清远见0次

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

助力顶级特效公司Wētā FX构建云上工作室,支持《阿凡达:水之道》高达33亿渲染线程小时的云上制作任务 北京2022年12月19日 /美通社/ -- 近期,时隔十三年重返大荧幕的阿凡达系列电影《阿凡达:水之道》在全球...

关键字: 亚马逊 线程 云计算 数字化

摩尔线程专注于研发设计全功能GPU芯片及相关产品,支持3D高速图形渲染、AI训练推理加速、超高清视频编解码和高性能科学计算等多种组合工作负载,能够为中国科技生态合作伙伴提供计算加速能力。

关键字: 摩尔 线程 GPU

作为丹纳赫生命科学平台旗下的重要运营公司,Pall颇尔公司将进一步加大在华投资,导入更高芯片线程的产线及技术,强化对国内客户的供应链稳定性。Pall颇尔中国已落实1100万美元的产能扩建投资,以进一步拓建北京工厂的半导体...

关键字: 半导体 供应链 微电子 线程

(全球TMT2021年12月16日讯)摩尔线程与浪潮在京签署元脑战略合作协议。摩尔线程与浪潮将发挥各自在技术、生态和产业等方面的领先优势,基于创新算力芯片和元脑生态平台展开多维和深度合作,联手开发领先的人工智能行业解决...

关键字: 线程

目录Java线程与OS线程的区别与关联JNI的作用JNIEnv和JavaVM是啥JNI中数据是如何传递的Java线程与Native(OS)线程的区别联系:Java线程其实是一层OS线程的封装,本质上就是OS线程。【以前版...

关键字: Android NI 线程 LOADER

线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源、什么时候需要考虑同步,怎么同步等等问题。

关键字: 线程 进程 JAVA

线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

关键字: 线程 进程 控制流

摘要:介绍了地基沉降远程数据采集系统服务器端软件的设计与实现方法。该软件能够并发处理多个远程客户端传送过来的数据,并将数据保存到数据库中,同时采用B/S架构对采集的数据进行管理和分析,从而实现对地基沉降远程采集数据的实时...

关键字: 地基沉降 远程数据采集 软件系统 线程

昨天我们用IntelI9的10核,每个核2个threads的机器跑了内核的编译:超线程SMT究竟可以快多少?今天,我换一台机器,采用AMDRyzen。 默认情况16核,每个核2个threads,共32个CPUs:下面编译...

关键字: zen 线程 SMT

众所周知,STL容器不是线程安全的。对于vector,即使写方(生产者)是单线程写入,但是并发读的时候,由于潜在的内存重新申请和对象复制问题,会导致读方(消费者)的迭代器失效。实际表现也就是招致了coredump。另外一...

关键字: 线程 ST
关闭
关闭