什么时候有人将std :: vector定义为thread_local?

时间:2016-11-11 12:58:22

标签: c++ multithreading vector stdvector thread-local

// Ghulam Mujtaba #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> static GLuint w=800,h=600; void init( void) { glShadeModel (GL_SMOOTH); glClearColor (1.0f, 1.0f, 1.0f, 1.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); } void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glPushMatrix(); glLoadIdentity(); glTranslatef(0.0,0.0,0.0); // glRotatef(0.0,0.0,0.0,0.0); //glScalef(0.0,0.0,0.0); glColor3f (1.0f, 0.0f, 1.0f); glutWireTeapot(1.0);//glutSolidTeapote(.25); glFlush(); glutSwapBuffers(); } void reshape (int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(90.0, (GLfloat) w/(GLfloat) h, 1.0, 50.0); //glFrustum (-2.0, 2.0, -2.0, 2.0, 1.5, 20.0); glMatrixMode (GL_MODELVIEW); glLoadIdentity(); //gluLookAt(0.0,0.0,15.0,0.0,-2.0,0.0,0.0,1.0,0.0); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowSize (w, h); glutInitWindowPosition (100, 100); glutCreateWindow ("TEAPOT"); init (); //glutKeyboardFunc(key); glutDisplayFunc(display); glutIdleFunc(display); glutReshapeFunc(reshape); glutMainLoop(); return 0; } 声明为std::vector是否有任何好处? 喜欢

thread_local

声明static unique_ptr<std::vector<ObjectA>> vecVariable; 为thread_local并未使其std::vectorpop_back()等操作同步。

与每个STL容器一样,如果有一个线程修改容器,则不会有并发线程读取或写入同一个容器,因此我无法在erase()erase()上执行{并发/多线程环境中的{1}}对象。

即使我将vector声明为pop_back(),我的代码也会在其中一个操作中崩溃。我知道我可能需要在锁定下执行这些操作,但我只想了解某人何时将vector定义为thread_local

2 个答案:

答案 0 :(得分:5)

thread_local并不意味着用于同步。它表示存储持续时间说明符(http://en.cppreference.com/w/cpp/language/storage_duration

举个例子:

#include <iostream>
#include <vector>
#include <thread>

thread_local std::vector<int> v;

void func()
{
  v.push_back(5);
  std::cout<< "t: "<< v.size() << std::endl;
}

int main() 
{
    v.push_back(3);
    v.push_back(5);
    std::thread t1(func);
    std::thread t2(func);
    std::cout<< "m: "<< v.size() << std::endl;
    t1.join();
    t2.join();
}

输出:

m: 2
t: 1
t: 1

thread_local所做的是为每个线程创建一个不同的向量。在该示例中,您可以看到主线程中的v有2个元素,而其他线程中的向量v每个只有1个元素。

当发生新线程时,程序还将仅为此线程创建新向量。线程结束时,矢量也会被破坏。

答案 1 :(得分:4)

thread_local会导致对象拥有线程存储,这意味着每个线程都有自己独立的对象实例。它不会以任何方式影响对象的线程安全性,因为您似乎建议您认为它应该。

如果您希望每个线程都拥有自己的变量实例,您可以声明vector变量或任何其他变量thread_local。如果您希望能够同时访问单个对象,则解决方案不是声明它thread_local,而是使用线程安全数据类型或适当的同步原语(例如,通过锁定和解锁{{1} })。