我是linux内核开发的新手。我试图学习线程创建和同步。我的最终目标是创建两个线程,两个线程使用由信号量保护的共享资源。
代码是
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<semaphore.h>
sem_t sema_obj;
pthread_t tid[2];
int shared_val = 0;
void* doSomeThing(void *arg)
{
unsigned long i = 0;
pthread_t id = pthread_self();
for(i=0;i<5;i++){
printf("\n going to wait %x\n",(unsigned int)id);
sem_wait(&sema_obj);
shared_val++;
sleep(1);
printf("\n %d The value of shared_val is %d in thread %x \n",(int)i, shared_val, (unsigned int)id);
sem_post(&sema_obj);
printf("\n gave up sem %x\n",(unsigned int)id);
}
for(i=0; i<(0xFFFFFFFF);i++);
return NULL;
}
int main(void)
{
int i = 0;
int err;
sem_init(&sema_obj, 0, 1);
while(i < 2)
{
pthread_attr_t attr;
struct sched_param param;
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
param.sched_priority = 50;
pthread_attr_setschedparam(&attr, ¶m);
//sched_setscheduler(current, SCHED_FIFO, ¶m);
err = pthread_create(&(tid[i]), &attr, &doSomeThing, NULL);
//err = pthread_create(&(tid[i]), NULL, &doSomeThing, NULL);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully 0x%X \n",(unsigned int)tid[i]);
i++;
}
enter code here
sleep(60);
return 0;
}
我正在用
编译它gcc -o threads_op -pthread -lrt threads.c
运行代码后,我看到:
Thread created successfully 0xB75CBB40
going to wait b75cbb40
Thread created successfully 0xB6DCAB40
going to wait b6dcab40
0 The value of shared_val is 1 in thread b75cbb40
gave up sem b75cbb40
going to wait b75cbb40
1 The value of shared_val is 2 in thread b75cbb40
gave up sem b75cbb40
going to wait b75cbb40
2 The value of shared_val is 3 in thread b75cbb40
gave up sem b75cbb40
going to wait b75cbb40
3 The value of shared_val is 4 in thread b75cbb40
gave up sem b75cbb40
going to wait b75cbb40
4 The value of shared_val is 5 in thread b75cbb40
gave up sem b75cbb40
0 The value of shared_val is 6 in thread b6dcab40
gave up sem b6dcab40
going to wait b6dcab40
1 The value of shared_val is 7 in thread b6dcab40
gave up sem b6dcab40
going to wait b6dcab40
2 The value of shared_val is 8 in thread b6dcab40
gave up sem b6dcab40
going to wait b6dcab40
3 The value of shared_val is 9 in thread b6dcab40
gave up sem b6dcab40
going to wait b6dcab40
4 The value of shared_val is 10 in thread b6dcab40
gave up sem b6dcab40
RTPRIO是&#39; - &#39;对于这个过程, S 1000 4551 4338 - 00:00:00 threads_op
有以下问题,
1)为什么线程不是实时并且采取我设置的优先级?
2)为什么信号量不会被两个线程交替锁定并更新共享变量?两个线程具有相同的优先级。
如果您逐步掌握了解Linux内核主题的教程,请分享。
答案 0 :(得分:3)
一些事情。
首先,我讨厌做一些事情,但你不是在做linux 内核开发。您正在编写一个在Linux上运行的多线程应用程序。因此,linux-kernel
标记不合适。内核开发是关于编写内核中构建的代码,例如调度程序,设备驱动程序,文件系统驱动程序等。
你的里面你的关键部分(例如sem_wait
和sem_post
之间)。你正在经历“线程饥饿”。请在此处查看我的回答:Thread Synchronization C++
由于您使用的是pthread,因此pthread_mutex_lock/pthread_mutex_unlock
可能会更好。
您还在使用printf
。即使是调试,它们也会破坏时序。
您正在尝试执行SCHED_FIFO但不检查返回代码。只有root可以设置一些RT调度程序和/或高[er]优先级。同样,用于调度优先级。
哇! SCHED_FIFO优先级为50?如果你真的得到它,任何高于11的东西都会比一些内部内核线程更优先考虑你。您可能会锁定系统稳固。 [*]
在您进入的阶段,在“全部进入”[使用RT调度程序等]之前,使用标准优先级的普通调度程序。你会惊讶于它的表现如何。在启动电压之前先调试线程同步代码/逻辑。
实际上,对于具有低延迟的确定性的平滑高响应性RT应用程序,我认为您需要更多地规划如何同步,线程之间的队列,类型锁定(例如RCU,trylocks,锁定尝试超时等)你需要多少个线程?每个人会做什么?你有每个伪代码吗?什么类型的线程环境(例如,消费者/生产者,主/从/工人)。你的线程是否会“偷窃”?等等,你会使用IPC消息,共享内存吗?多少数据?线程之间的数据带宽是多少?
[*]我知道这一点的原因是我是一个实时系统的开发人员,该系统有50个线程,8个内核,并且与多个设备驱动程序和FPGA以及大量DMA持续交互[所以,我们有用PCIe总线分析仪测量它,以确保总线有足够的带宽]。它现在是一种运输产品。
答案 1 :(得分:0)
要实际回答问题:
1)您如何知道线程不是实时的?实时过程不同于实时线程。如果您使用sudo或以root用户身份运行此程序,则它应具有实时优先级。
2)信号量不能保证是公平的。如果您希望另一个线程有机会增加该值,则必须使用信号量将sleep()调用移至关键部分之外。发布(释放)信号量并不一定会导致重新计划,因此释放线程完全有可能立即循环返回并再次等待(获取)信号量。