线程安全地通过多线程在c ++中写入流

宝莲

我正在尝试创建多个线程,并尝试找出调度顺序以及它们何时完成。每次线程获得CPU时,它都会执行一些计算,然后作为繁忙的等待时间等待x倍(1000ns),然后进入睡眠状态。每次一个线程获取CPU时,它也会打印时间,以便以后可以找到特定线程获取CPU的时间和顺序。

为了使线程安全,我正在使用互斥锁,但是仍然不能给出正确的结果。我在哪里犯错?任何帮助将不胜感激。

我在Linux下使用g ++。

注意:我无法使用文件,因为在这种情况下文件打开/关闭会产生开销。

这是我的程序输出

Output :

$ sort -t , -k4,4n -k5,5n -k6,6n >a.txt
$ head a.txt 
thread,   thread_no, iteration, time_min, time_sec, time_microsec    
foo,
foo,14,987
foo,32
foo,32,985,
foo,57,970
foo,71,933,
foo,71,933,
foo,71,933,
foo,71,933,

$ tail a.txt  
thread,   thread_no, iteration, time_min, time_sec, time_microsec
foo,98,991,40,05,935379 
foo,98,992,40,05,935442 
foo,98,993,40,05,935506 
foo,98,994,40,05,935569 
foo,98,995,40,05,935633 
foo,98,996,40,05,935697 
foo,98,997,40,05,935760 
foo,98,998,40,05,935824 
foo,98,999,40,05,937914 
foo,98,1000,40,05,937994

根据Bart van Nierop在释放互斥锁之前添加out.flush()之后的评论,

这是结果。$ head a.txt

foo,
foo,
foo,48,991,
foo,65,
foo,95,
foo,97
foo,10,1,15,59,288329 
foo,10,1,15,59,288329 
foo,10,1,15,59,288329

这是我的程序

#include <pthread.h>
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <sys/time.h>
#include <time.h>       /* time_t, struct tm, time, localtime */
#include <mutex>          // std::mutex
#include <sstream>

#define BILLION  1000000000L
#define NUM_THREADS 100

std::mutex mtx;           // mutex for critical section

using namespace std;


std::string now_str()
{
    struct timeval tv;
    struct timezone tz;
    struct tm *tm;
    gettimeofday(&tv, &tz);
    tm=localtime(&tv.tv_sec);
    char buf[40];
    sprintf(buf,"%02d,%02d,%ld ", tm->tm_min,tm->tm_sec, tv.tv_usec); 
    return buf;
}


std::ostringstream out;  
/* This is our thread function.  It is like main(), but for a thread*/
void *threadFunc(void *arg)
{ 
      int s,j;
      pthread_attr_t gattr;

      // Assigning SCHED_RR policy 

      j = SCHED_RR;
      s = pthread_attr_setschedpolicy(&gattr, j);
      if (s != 0) 
        printf( "pthread_attr_setschedpolicy");

      s = pthread_attr_getschedpolicy(&gattr, &j);
      if (s != 0)
        printf( "pthread_attr_getschedpolicy");


    struct timespec start, stop;
    double accum;

    char *str;
    int i = 0,k=0;

    str=(char*)arg;

    while(i < 1000)
    {

        ++i;

        // do something here

        mtx.lock(); 
        out << "\nfoo," <<str<<","<<i<<"," <<now_str(); // note the timing of thread
        mtx.unlock();  


    if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) 
    {
          perror( "clock gettime" );
          exit( EXIT_FAILURE );
    }

    // busy wait for 1000ns
    do

    { 
        if( clock_gettime( CLOCK_REALTIME, &stop) == -1 ) 
        {
              perror( "clock gettime" );
              exit( EXIT_FAILURE );
            }

        accum = ( stop.tv_sec - start.tv_sec )* BILLION + ( stop.tv_nsec - start.tv_nsec ) ;

    }while(accum < 1000);

        // block the thread, to allow other thread to run
        usleep(1);
    }
    std::cout<<out.str();

    return NULL;
}

int main(void)
{

    pthread_t pth[NUM_THREADS];  
    int i = 0;
pthread_create(&pth[0],NULL, threadFunc,  (void *) "0"); 
pthread_create(&pth[1],NULL, threadFunc,  (void *) "1"); 
.
.
.

pthread_create(&pth[98],NULL, threadFunc,  (void *) "98"); 
pthread_create(&pth[99],NULL, threadFunc,  (void *) "99"); 

    for(int k=0;k<NUM_THREADS;k++)
    pthread_join(pth[k],NULL);

    return 0;
}
杰伊

在Google上稍作搜索,看来ostringstream不是线程安全的

要获得所需的内容,可以滚动自己的日志记录。

一种方法是写入大缓冲区的末尾:

uint64_t offset = 0;
char buffer[ 200000 ];

使用互斥量写入:

mtx.lock(); 
offset += sprintf( buffer + offset, "\nfoo,%s,%d,%s", str, i, now_str().c_str() );
mtx.unlock();  

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

我可以在多线程C ++中安全地使用int吗?

如何在要抓取的网址列表中安全地进行多线程处理?

如何在C ++中写入输入流cin

在C程序中,使用Picocom读取/写入流

C#使用线程堆安全地写入文本文件

如果文件中的项目数量非常少,是否可以安全地使用Spring Batch多线程步骤?

在C ++中通过多线程将数据同时插入到单个MySQL表中

通过多线程增加JavaFX中ProgressBar的进度

在C#.net中通过多线程读取文本文件数据

如何在Java中安全地访问数组线程?

在WPF中安全地访问UI(主)线程

在C ++ 11中的线程之间高效,安全地传递不可变对象

线程安全地从另一个线程中调用TimerTask

AXUIElement.h 中的函数可以从主线程以外的线程安全地调用吗?

通过多线程与使用hbase / hive之类的选项写入HDFS

假设没有“并发访问”,则将内存块安全地“借给” C中的另一个线程

多个线程可以安全地同时将相同的值写入相同的变量吗?

C ++中的多线程

通过多线程无锁定地将项目添加到同一列表中是否正确?

安全地移动在访问其他成员的成员线程中运行lambda的对象

在两个线程中安全地修改变量

C++:在多线程程序中写入文件

安全地中止线程列表中的线程

C中的多线程-WINAPI

C ++中的多线程混乱

我可以仅使用std :: atomic而不使用std :: mutex在C ++中的线程之间安全地共享变量吗?

为什么在C#中安全地将委托分配给本地复制线程,任何代码都可以证明这一点?

Java,在多线程环境中通过哈希将传入的工作均匀地划分

在C#中从多个线程写入布尔变量是否安全?